From c7c21cf90d37d243bcf1bf8fed46fd42c7b0b3b2 Mon Sep 17 00:00:00 2001 From: rajesh Date: Fri, 27 Jun 2025 20:04:39 +0530 Subject: [PATCH 01/75] Done ticket GEPAFINBE-231 --- .../tendermanagement/dao/ApplicationDao.java | 83 ++++++++++++++++++- .../dao/ApplicationEvaluationDao.java | 13 ++- .../dao/EmailNotificationDao.java | 31 ++++++- .../dao/SystemEmailTemplatesDao.java | 4 +- .../entities/SystemEmailTemplatesEntity.java | 3 +- .../enums/ApplicationStatusForEvaluation.java | 3 +- .../enums/ApplicationStatusTypeEnum.java | 3 +- .../enums/EmailScenarioTypeEnum.java | 3 +- .../enums/UserActionContextEnum.java | 2 + .../repositories/ApplicationRepository.java | 3 + .../EvaluationCriteriaRepository.java | 2 + .../service/ApplicationService.java | 5 +- .../service/impl/ApplicationServiceImpl.java | 6 ++ .../web/rest/api/ApplicationApi.java | 15 ++++ .../api/impl/ApplicationApiController.java | 21 +++++ .../db/changelog/db.changelog-1.0.0.xml | 4 + ...template_technical_evaluation_rejected.sql | 31 +++++++ 17 files changed, 217 insertions(+), 15 deletions(-) create mode 100644 src/main/resources/db/dump/insert_system_email_template_technical_evaluation_rejected.sql diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java index 198a4ede..a90f9c4a 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java @@ -56,13 +56,11 @@ import org.springframework.web.multipart.MultipartFile; import jakarta.servlet.http.HttpServletRequest; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStreamWriter; +import java.io.*; import java.lang.reflect.Method; import java.math.BigDecimal; +import java.nio.charset.StandardCharsets; import java.sql.Timestamp; import java.text.MessageFormat; import java.text.SimpleDateFormat; @@ -217,6 +215,9 @@ public class ApplicationDao { @Autowired private ApplicationEvaluationDao applicationEvaluationDao; + @Autowired + private EvaluationCriteriaRepository evaluationCriteriaRepository; + public final Random random = new Random(); public ApplicationResponseBean createApplication(HttpServletRequest request, ApplicationRequestBean applicationRequestBean, Long formId, Long applicationId) { @@ -2419,4 +2420,78 @@ public class ApplicationDao { emailNotificationDao.sendMail(hub.getId(), subject, body, List.of(GepafinConstant.RINALDO_EMAIL),emailLogRequest); } + public byte[] downloadRankingCsv(Long callId) { + CallEntity callEntity = callService.validateCall(callId); + + BigDecimal scoreList = BigDecimal.ZERO; + List evaluationCriteriaEntities = + evaluationCriteriaRepository.findByCallIdAndIsDeletedFalse(callId); + List headers = Arrays.asList( + "ApplicationID", + "VatNumber", + "Company Name", + "Protocol", + "Requested Amount", + "Status", + "Total Score", + "Individual Scores" + ); + + + for (EvaluationCriteriaEntity evaluationCriteria : evaluationCriteriaEntities) { + scoreList = scoreList.add(evaluationCriteria.getScore()); + } + + List applications = + applicationRepository.findByCallIdAndIsDeletedFalseAndStatusIn(callId,List.of(ApplicationStatusForEvaluation.APPROVED.getValue(),ApplicationStatusForEvaluation.ADMISSIBLE.getValue(),ApplicationStatusForEvaluation.TECHNICAL_EVALUATION.getValue())); + + // Collect all rows with totalScore for sorting + List> rows = new ArrayList<>(); + + for (ApplicationEntity app : applications) { + CompanyEntity company = companyService.validateCompany(app.getCompanyId()); + String name = company.getCompanyName(); + String vat = company.getVatNumber(); + Long applicationId = app.getId(); + ProtocolEntity protocolEntity = app.getProtocol(); + Long protocol = (protocolEntity != null) ? protocolEntity.getProtocolNumber() : 0L; + BigDecimal requestedAmount = app.getAmountRequested(); + String status = app.getStatus(); + + ApplicationEvaluationEntity applicationEvaluationEntity = + applicationEvaluationRepository.findByApplicationId(app.getId()); + + BigDecimal totalScore = applicationEvaluationDao.calculateTotalScore( + applicationEvaluationEntity.getCriteria() + ); + + rows.add(Arrays.asList( + applicationId, + vat, + name, + protocol, + requestedAmount, + status, + scoreList, + totalScore + )); + } + + // 5. Write the CSV using Commons CSV, with headers: + ByteArrayOutputStream out = new ByteArrayOutputStream(); + try (OutputStreamWriter writer = new OutputStreamWriter(out, StandardCharsets.UTF_8); + CSVPrinter csvPrinter = new CSVPrinter(writer, + CSVFormat.DEFAULT.withHeader(headers.toArray(new String[0])))) { + + for (List row : rows) { + csvPrinter.printRecord(row); + } + csvPrinter.flush(); + } catch (IOException e) { + throw new RuntimeException("Error while generating CSV", e); + } + + return out.toByteArray(); + } + } diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java index 3cb7237a..9fa68a28 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java @@ -1910,7 +1910,8 @@ public class ApplicationEvaluationDao { Optional existingEntityOptional = applicationEvaluationRepository.findByAssignedApplicationsEntity_IdAndIsDeletedFalse( assignedApplicationsEntity.getId()); ApplicationEvaluationEntity entity; - + UserEntity user=userService.validateUser(application.getUserId()); + HubEntity hub=user.getHub(); EmailSendResponse emailSendResponse = new EmailSendResponse(); if (existingEntityOptional.isPresent()) { ApplicationEvaluationEntity existingEntity = existingEntityOptional.get(); @@ -1940,7 +1941,13 @@ public class ApplicationEvaluationDao { application.setStatus(newStatus.getValue()); log.info("Application status updated to {} for applicationId: {}", newStatus, application.getId()); } - application = applicationRepository.save(application); + + if(newStatus.equals(ApplicationStatusForEvaluation.TECHNICAL_EVALUATION_REJECTED) && Boolean.TRUE.equals(application.getStatus().equals(ApplicationStatusTypeEnum.ADMISSIBLE.getValue()))) { + application.setStatus(newStatus.getValue()); + log.info("Application status updated to {} for applicationId: {}", newStatus, application.getId()); + emailNotificationDao.sendMailForApplicationTechnicalEvaluationRejected(application,hub,existingEntity); + } + application = applicationRepository.save(application); /** This code is responsible for adding a version history log for the "Update Application" operation. **/ loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplicationEntity).newData(application).build()); @@ -2573,7 +2580,7 @@ public class ApplicationEvaluationDao { } } - private BigDecimal calculateTotalScore(String criteriaJson){ + public BigDecimal calculateTotalScore(String criteriaJson){ try { ObjectMapper objectMapper = new ObjectMapper(); // Convert JSON string to List of Maps diff --git a/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java index 59d6193f..462958cb 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java @@ -73,6 +73,9 @@ public class EmailNotificationDao { @Value("${rinaldo_email}") private String rinaldoEmail; + @Autowired + private SystemEmailTemplatesDao systemEmailTemplatesDao; + private void sendEmail(ApplicationEntity applicationEntity, SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum templateType, Map bodyPlaceholders, List additionalRecipients, Long amendmentId) { @@ -355,4 +358,30 @@ public class EmailNotificationDao { throw new IllegalArgumentException("Failed to parse email configuration JSON", e); } } -} \ No newline at end of file + public void sendMailForApplicationTechnicalEvaluationRejected(ApplicationEntity applicationEntity,HubEntity hub,ApplicationEvaluationEntity applicationEvaluationEntity) { + + Map bodyPlaceholders = prepareEmailPlaceholdersForTechnicalEvaluationRejected(applicationEntity,hub,applicationEvaluationEntity); + sendEmail(applicationEntity, SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum.INADMISSIBILITY_NOTIFICATION_DUE_TO_TECHNICAL_EVALUATION_FAILURE, bodyPlaceholders, null, + null); + } + public Map prepareEmailPlaceholdersForTechnicalEvaluationRejected(ApplicationEntity applicationEntity,HubEntity hub,ApplicationEvaluationEntity applicationEvaluationEntity) { + Map bodyPlaceholders = new HashMap<>(); + bodyPlaceholders.put("{{call_name}}", applicationEntity.getCall().getName()); + String protocolNumber = applicationEntity.getProtocol().getExternalProtocolNumber(); + if (protocolNumber == null) { + protocolNumber = String.valueOf(applicationEntity.getProtocol().getProtocolNumber()); + } + bodyPlaceholders.put("{{protocol_number}}", protocolNumber); + String protocolDate = DateTimeUtil.formatLocalDateTime(applicationEntity.getProtocol().getCreatedDate(), GepafinConstant.DD_MM_YYYY); + if (applicationEntity.getProtocol().getExternalProtocolDate() != null) { + protocolDate = DateTimeUtil.formatLocalDateTime(applicationEntity.getProtocol().getExternalProtocolDate(), GepafinConstant.DD_MM_YYYY); + } + bodyPlaceholders.put("{{protocol_date}}", protocolDate); + bodyPlaceholders.put("{{protocol_time}}", DateTimeUtil.parseLocalTimeToString(applicationEntity.getProtocol().getTime(), GepafinConstant.HH_MM_SS)); + bodyPlaceholders.put("{{email_signature}}", hub.getEmailSignature()); + bodyPlaceholders.put("{{platform_link}}", hub.getDomainName()); + bodyPlaceholders.put("{{form_text}}", applicationEvaluationEntity.getMotivation()); + + return bodyPlaceholders; + } + } \ No newline at end of file diff --git a/src/main/java/net/gepafin/tendermanagement/dao/SystemEmailTemplatesDao.java b/src/main/java/net/gepafin/tendermanagement/dao/SystemEmailTemplatesDao.java index 8808abfd..2362b77e 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/SystemEmailTemplatesDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/SystemEmailTemplatesDao.java @@ -116,7 +116,7 @@ public class SystemEmailTemplatesDao { return htmlContent; } - private String replaceEmailSignature(HubEntity hub, String htmlContent, Map languageMap) { + public String replaceEmailSignature(HubEntity hub, String htmlContent, Map languageMap) { String emailSignature = defaultEmailSignature; if(hub != null && Boolean.FALSE.equals(StringUtils.isEmpty(hub.getEmailSignature()))){ emailSignature = hub.getEmailSignature(); @@ -124,7 +124,7 @@ public class SystemEmailTemplatesDao { return htmlContent.replace("{{email_signature}}", emailSignature); } - private String replacePlatformLinkPlaceholder(HubEntity hub, String htmlContent, Map languageMap) { + public String replacePlatformLinkPlaceholder(HubEntity hub, String htmlContent, Map languageMap) { String platformLink = feBaseUrl; if(hub != null && Boolean.FALSE.equals(StringUtils.isEmpty(hub.getDomainName()))){ platformLink = hub.getDomainName(); diff --git a/src/main/java/net/gepafin/tendermanagement/entities/SystemEmailTemplatesEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/SystemEmailTemplatesEntity.java index a4c40863..1ac63bae 100644 --- a/src/main/java/net/gepafin/tendermanagement/entities/SystemEmailTemplatesEntity.java +++ b/src/main/java/net/gepafin/tendermanagement/entities/SystemEmailTemplatesEntity.java @@ -55,7 +55,8 @@ public class SystemEmailTemplatesEntity extends BaseEntity { USER_ONBOARDING_BANDI("USER_ONBOARDING_BANDI"), PASSWORD_RESET("PASSWORD_RESET"), INADMISSIBILITY_TEMPLATE("INADMISSIBILITY_NOTIFICATION"), - APPLICATION_SUBMISSION_FAILURE_NOTIFICATION("APPLICATION_SUBMISSION_FAILURE_NOTIFICATION"); + APPLICATION_SUBMISSION_FAILURE_NOTIFICATION("APPLICATION_SUBMISSION_FAILURE_NOTIFICATION"), + INADMISSIBILITY_NOTIFICATION_DUE_TO_TECHNICAL_EVALUATION_FAILURE("INADMISSIBILITY_NOTIFICATION_DUE_TO_TECHNICAL_EVALUATION_FAILURE"); private String value; SystemEmailTemplatesEntityTypeEnum(String value) { diff --git a/src/main/java/net/gepafin/tendermanagement/enums/ApplicationStatusForEvaluation.java b/src/main/java/net/gepafin/tendermanagement/enums/ApplicationStatusForEvaluation.java index f0f6acb8..d9c3c45e 100644 --- a/src/main/java/net/gepafin/tendermanagement/enums/ApplicationStatusForEvaluation.java +++ b/src/main/java/net/gepafin/tendermanagement/enums/ApplicationStatusForEvaluation.java @@ -6,7 +6,8 @@ public enum ApplicationStatusForEvaluation { APPROVED("APPROVED"), REJECTED("REJECTED"), ADMISSIBLE("ADMISSIBLE"), - TECHNICAL_EVALUATION("TECHNICAL_EVALUATION"); + TECHNICAL_EVALUATION("TECHNICAL_EVALUATION"), + TECHNICAL_EVALUATION_REJECTED("TECHNICAL_EVALUATION_REJECTED"); private String value; diff --git a/src/main/java/net/gepafin/tendermanagement/enums/ApplicationStatusTypeEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/ApplicationStatusTypeEnum.java index 041ec85a..3afbc3ad 100644 --- a/src/main/java/net/gepafin/tendermanagement/enums/ApplicationStatusTypeEnum.java +++ b/src/main/java/net/gepafin/tendermanagement/enums/ApplicationStatusTypeEnum.java @@ -16,7 +16,8 @@ public enum ApplicationStatusTypeEnum { APPOINTMENT("APPOINTMENT"), NDG("NDG"), ADMISSIBLE("ADMISSIBLE"), - TECHNICAL_EVALUATION("TECHNICAL_EVALUATION"); + TECHNICAL_EVALUATION("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 908e554d..ab25ad25 100644 --- a/src/main/java/net/gepafin/tendermanagement/enums/EmailScenarioTypeEnum.java +++ b/src/main/java/net/gepafin/tendermanagement/enums/EmailScenarioTypeEnum.java @@ -12,7 +12,8 @@ public enum EmailScenarioTypeEnum { USER_CREATION("USER_CREATION"), PASSWORD_RESET_REQUEST("PASSWORD_RESET_REQUEST"), APPLICATION_REJECTED("APPLICATION_REJECTED"), - APPLICATION_SUBMISSION_FAILURE("APPLICATION_SUBMISSION_FAILURE"); + APPLICATION_SUBMISSION_FAILURE("APPLICATION_SUBMISSION_FAILURE"), + APPLICATION_TECHNICAL_EVALUATION_REJECTED("APPLICATION_TECHNICAL_EVALUATION_REJECTED"); 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 1de6b333..4200e361 100644 --- a/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java +++ b/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java @@ -47,6 +47,8 @@ public enum UserActionContextEnum { GET_NEXT_PREVIOUS_FORM("GET_NEXT_PREVIOUS_FORM"), DOWNLOAD_APPLICATION_DOC_ZIP("DOWNLOAD_APPLICATION_DOC_ZIP"), READMIT_APPLICATION("READMIT_APPLICATION"), + DOWNLOAD_CSV_BY_CALL_ID("DOWNLOAD_CSV_BY_CALL_ID"), + DOWNLOAD_CSV_AS_PER_RANKING("DOWNLOAD_CSV_AS_PER_RANKING"), /** FAQ action context **/ CREATE_FAQ("CREATE_FAQ"), diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationRepository.java index c760689a..37d2f270 100644 --- a/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationRepository.java +++ b/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationRepository.java @@ -181,4 +181,7 @@ public interface ApplicationRepository extends JpaRepository findByCallIdAndIsDeletedFalseAndStatusIn(Long callId,List status); + + } diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/EvaluationCriteriaRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/EvaluationCriteriaRepository.java index 1a7f7ccd..8c939956 100644 --- a/src/main/java/net/gepafin/tendermanagement/repositories/EvaluationCriteriaRepository.java +++ b/src/main/java/net/gepafin/tendermanagement/repositories/EvaluationCriteriaRepository.java @@ -18,4 +18,6 @@ public interface EvaluationCriteriaRepository extends JpaRepository findByCallIdAndLookupDataTypeAndIsDeletedFalse(Long callId, String type); // List findByCallId(Long callId); + List findByCallIdAndIsDeletedFalse(Long callId); + } diff --git a/src/main/java/net/gepafin/tendermanagement/service/ApplicationService.java b/src/main/java/net/gepafin/tendermanagement/service/ApplicationService.java index c7af4f88..9cc2ea22 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/ApplicationService.java +++ b/src/main/java/net/gepafin/tendermanagement/service/ApplicationService.java @@ -52,4 +52,7 @@ public interface ApplicationService { public ApplicationResponse readmitApplication(HttpServletRequest request, Long applicationId); - } + public byte[] downloadRankingCsv(HttpServletRequest request, Long callId); + + +} diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationServiceImpl.java index 357661d1..aca38d23 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationServiceImpl.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationServiceImpl.java @@ -176,4 +176,10 @@ public class ApplicationServiceImpl implements ApplicationService { UserEntity userEntity = validator.validateUser(request); return applicationDao.readmitApplication(request, applicationId); } + + @Override + public byte[] downloadRankingCsv(HttpServletRequest request, Long callId) { + UserEntity userEntity = validator.validateUser(request); + return applicationDao.downloadRankingCsv(callId); + } } diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/ApplicationApi.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/ApplicationApi.java index a18e6852..b64b3951 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/ApplicationApi.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/ApplicationApi.java @@ -252,6 +252,21 @@ public interface ApplicationApi { ResponseEntity> readmitApplication(HttpServletRequest request, @Parameter(description = "The application id", required = true) @PathVariable("applicationId") Long applicationId); + @Operation(summary = "Api to download application data as a CSV file as per ranking", + 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 = "/call/{callId}/ranking-csv") + @PreAuthorize("hasRole('ROLE_SUPER_ADMIN') || hasRole('ROLE_INSTRUCTOR_MANAGER')") + public ResponseEntity downloadRankingCsv( + HttpServletRequest request, @Parameter(description = "The call id", required = true) @PathVariable(value = "callId", required = true) Long callId); + } diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/ApplicationApiController.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/ApplicationApiController.java index 840711ae..76946420 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/ApplicationApiController.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/ApplicationApiController.java @@ -27,6 +27,8 @@ import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; import org.slf4j.Logger; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; import java.util.List; @@ -236,6 +238,10 @@ public class ApplicationApiController implements ApplicationApi { } @Override public ResponseEntity exportCsv(HttpServletRequest request, Long callId) { + + loggingUtil.logUserAction( + UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.DOWNLOAD).actionContext(UserActionContextEnum.DOWNLOAD_CSV_BY_CALL_ID).build()); + byte[] csvBytes =applicationService.exportCsv(request,callId); return ResponseEntity.ok() .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=applications.csv") @@ -254,4 +260,19 @@ public class ApplicationApiController implements ApplicationApi { return ResponseEntity.status(HttpStatus.OK) .body(new Response<>(applicationResponse, Status.SUCCESS, Translator.toLocale(GepafinConstant.READMIT_APPLICATION_SUCCESS))); } + + @Override + public ResponseEntity downloadRankingCsv(HttpServletRequest request, Long callId) { + loggingUtil.logUserAction( + UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.DOWNLOAD).actionContext(UserActionContextEnum.DOWNLOAD_CSV_AS_PER_RANKING).build()); + + byte[] csvBytes =applicationService.downloadRankingCsv(request,callId); + String dateString = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd")); + String fileName = "call_" + callId + "_" + dateString + ".csv"; + + return ResponseEntity.ok() + .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + fileName) + .contentType(MediaType.APPLICATION_OCTET_STREAM) + .body(csvBytes); + } } 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 147dd7f7..c16d810c 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 @@ -2980,4 +2980,8 @@ + + + diff --git a/src/main/resources/db/dump/insert_system_email_template_technical_evaluation_rejected.sql b/src/main/resources/db/dump/insert_system_email_template_technical_evaluation_rejected.sql new file mode 100644 index 00000000..7b76a13d --- /dev/null +++ b/src/main/resources/db/dump/insert_system_email_template_technical_evaluation_rejected.sql @@ -0,0 +1,31 @@ +INSERT INTO gepafin_schema.system_email_template +(template_name, "type", html_content, subject, "json", "system", is_deleted, created_date, updated_date, email_scenario) +VALUES +( + 'Application Technical Evaluation Rejected Template', + 'INADMISSIBILITY_NOTIFICATION_DUE_TO_TECHNICAL_EVALUATION_FAILURE', + ' + +
+

Buongiorno,

+

Si comunica che, in riferimento alla domanda a valere sul bando “{{call_name}}” di cui al + Protocollo n. {{protocol_number}} del {{protocol_date}} alle {{protocol_time}}, + a stessa è stata sottoposta a valutazione tecnica ed economico finanziaria + con esito negativo

+

Le motivazioni sono le seguenti: {{form_text}}

+

Vi ricordiamo che i Beneficiari, in caso di mancato accoglimento della Domanda di Finanziamento agevolato, entro 10 giorni dalla data di ricevimento della presente potranno formulare ricorso al Gestore tramite + modello disponibile nello sportello online + {{platform_link}}, e sul sito internet home - ND Credit Repair , nella sezione dedicata ai Bandi e Avvisi pubblici.

+

Distinti Saluti,

+

{{email_signature}}

+
+ + ', + 'BANDO – "{{call_name}}" – Esito negativo della valutazione tecnica – {{company_name}}', + null, + true, + false, + CURRENT_TIMESTAMP, + CURRENT_TIMESTAMP, + 'APPLICATION_TECHNICAL_EVALUATION_REJECTED' +); From cbed4500cdbb841d36ca28dfb0427c21fee3a519 Mon Sep 17 00:00:00 2001 From: rajesh Date: Mon, 30 Jun 2025 16:46:56 +0530 Subject: [PATCH 02/75] Updated logic for application status --- .../tendermanagement/dao/ApplicationEvaluationDao.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java index 9fa68a28..215a5e24 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java @@ -1932,17 +1932,17 @@ public class ApplicationEvaluationDao { } } - if(newStatus.equals(ApplicationStatusForEvaluation.TECHNICAL_EVALUATION) && Boolean.TRUE.equals(application.getStatus().equals(ApplicationStatusTypeEnum.ADMISSIBLE.getValue()))){ + if(newStatus.equals(ApplicationStatusForEvaluation.TECHNICAL_EVALUATION)){ log.info("Processing technical evaluation for applicationId: {}", application.getId()); processTechnicalEvaluation(application.getId(), application, newStatus); } - if((newStatus.equals(ApplicationStatusForEvaluation.APPROVED) || newStatus.equals(ApplicationStatusForEvaluation.REJECTED)) && application.getStatus().equals(ApplicationStatusTypeEnum.EVALUATION.getValue())) { + if((newStatus.equals(ApplicationStatusForEvaluation.APPROVED) || newStatus.equals(ApplicationStatusForEvaluation.REJECTED))) { application.setStatus(newStatus.getValue()); log.info("Application status updated to {} for applicationId: {}", newStatus, application.getId()); } - if(newStatus.equals(ApplicationStatusForEvaluation.TECHNICAL_EVALUATION_REJECTED) && Boolean.TRUE.equals(application.getStatus().equals(ApplicationStatusTypeEnum.ADMISSIBLE.getValue()))) { + if(newStatus.equals(ApplicationStatusForEvaluation.TECHNICAL_EVALUATION_REJECTED)) { application.setStatus(newStatus.getValue()); log.info("Application status updated to {} for applicationId: {}", newStatus, application.getId()); emailNotificationDao.sendMailForApplicationTechnicalEvaluationRejected(application,hub,existingEntity); From b7456a87eeed9455831a32ec761e23fc194ecad3 Mon Sep 17 00:00:00 2001 From: rajesh Date: Tue, 1 Jul 2025 11:41:21 +0530 Subject: [PATCH 03/75] Updated message in evaluation API --- .../constants/GepafinConstant.java | 2 +- .../dao/ApplicationEvaluationDao.java | 16 +++++++++++----- .../impl/ApplicationEvaluationApiController.java | 2 +- src/main/resources/message_en.properties | 1 + src/main/resources/message_it.properties | 1 + 5 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java b/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java index 3874fc83..42857d23 100644 --- a/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java +++ b/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java @@ -574,7 +574,7 @@ public class GepafinConstant { public static final String CREATE_NDG="CHECK_OR_CREATE_NDG_CODE"; public static final String NDG_NOT_FOUND="ndg.not.found"; public static final String EMAIL_PEC_REQUIRED="email.pec.cannot.null"; - + public static final String USER_REQUEST_COMPLETED="user.request.completed"; } diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java index 215a5e24..ccc4e315 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java @@ -1946,12 +1946,15 @@ public class ApplicationEvaluationDao { application.setStatus(newStatus.getValue()); log.info("Application status updated to {} for applicationId: {}", newStatus, application.getId()); emailNotificationDao.sendMailForApplicationTechnicalEvaluationRejected(application,hub,existingEntity); + application.setDateRejected(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); + emailSendResponse = emailDao.buildEmailSendResponseFromRequest(request); + responses = List.of(emailSendResponse); + if (!Boolean.TRUE.equals(emailSendResponse.getIsEmailSend())) { + saveEmailSendResponseToEvaluation(emailSendResponse, existingEntity); + } } application = applicationRepository.save(application); - /** This code is responsible for adding a version history log for the "Update Application" operation. **/ - loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplicationEntity).newData(application).build()); - ApplicationEvaluationEntity oldApplicationEvaluation = Utils.getClonedEntityForData(existingEntity); AssignedApplicationsEntity oldAssignedApplication = Utils.getClonedEntityForData(assignedApplicationsEntity); @@ -1961,7 +1964,7 @@ public class ApplicationEvaluationDao { throw new CustomValidationException(Status.BAD_REQUEST,Translator.toLocale(GepafinConstant.APPLICATION_CANNOT_APPROVED_OR_REJECTED)); } String statusType = application.getStatus(); - if (application.getStatus().equals(ApplicationStatusTypeEnum.APPROVED.getValue()) || application.getStatus().equals(ApplicationStatusTypeEnum.REJECTED.getValue())) { + if (application.getStatus().equals(ApplicationStatusTypeEnum.APPROVED.getValue()) || application.getStatus().equals(ApplicationStatusTypeEnum.REJECTED.getValue()) || application.getStatus().equals(ApplicationStatusTypeEnum.TECHNICAL_EVALUATION_REJECTED.getValue())) { existingEntity.setStatus(ApplicationEvaluationStatusTypeEnum.CLOSE.getValue()); existingEntity.setClosingDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); assignedApplicationsEntity.setStatus(AssignedApplicationEnum.CLOSE.getValue()); @@ -1976,7 +1979,7 @@ public class ApplicationEvaluationDao { entity = applicationEvaluationRepository.save(existingEntity); assignedApplicationsRepository.save(assignedApplicationsEntity); - if (application.getStatus().equals(ApplicationStatusTypeEnum.APPROVED.getValue()) || application.getStatus().equals(ApplicationStatusTypeEnum.REJECTED.getValue())) { + if (application.getStatus().equals(ApplicationStatusTypeEnum.APPROVED.getValue()) || application.getStatus().equals(ApplicationStatusTypeEnum.REJECTED.getValue()) || application.getStatus().equals(ApplicationStatusTypeEnum.TECHNICAL_EVALUATION_REJECTED.getValue())) { /** This code is responsible for adding a version history log for the "Update Application Evaluation" operation. **/ loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplicationEvaluation).newData(entity).build()); @@ -2006,6 +2009,9 @@ public class ApplicationEvaluationDao { notificationDao.sendNotificationToBeneficiary(application, NotificationTypeEnum.EVALUATION_RESULT); } + /** This code is responsible for adding a version history log for the "Update Application" operation. **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplicationEntity).newData(application).build()); + Map placeHolders = new HashMap<>(); placeHolders.put("{{call_name}}", application.getCall().getName()); String protocolNumber=application.getProtocol().getExternalProtocolNumber(); diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/ApplicationEvaluationApiController.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/ApplicationEvaluationApiController.java index 50eadb36..2f6bbcb3 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/ApplicationEvaluationApiController.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/ApplicationEvaluationApiController.java @@ -46,7 +46,7 @@ public class ApplicationEvaluationApiController implements ApplicationEvaluation request, evaluationRequest, assignedApplicationsId); return ResponseEntity.status(HttpStatus.CREATED) - .body(new Response<>(response, Status.SUCCESS, Translator.toLocale(GepafinConstant.EVALUATION_CREATED_SUCCESSFULLY))); + .body(new Response<>(response, Status.SUCCESS, Translator.toLocale(GepafinConstant.USER_REQUEST_COMPLETED))); } diff --git a/src/main/resources/message_en.properties b/src/main/resources/message_en.properties index 8d9aae03..a706e568 100644 --- a/src/main/resources/message_en.properties +++ b/src/main/resources/message_en.properties @@ -410,3 +410,4 @@ no.email.log.msg = No failed emails found for given userActionId. user.action.id.not.found = User Action id not found. ndg.not.found=NDG not found. email.pec.cannot.null=Email pec is required. +user.request.completed=User request completed successfully. diff --git a/src/main/resources/message_it.properties b/src/main/resources/message_it.properties index 5a94ede6..f4246425 100644 --- a/src/main/resources/message_it.properties +++ b/src/main/resources/message_it.properties @@ -401,3 +401,4 @@ no.email.log.msg = Nessuna email trovata per userActionId specificato. user.action.id.not.found = ID azione utente non trovato. ndg.not.found=NDG non trovato. email.pec.cannot.null=L'indirizzo email pec obbligatorio. +user.request.completed=Richiesta utente completata con successo. From b12b0a46659bdc2d601d65b69317f50448a65c18 Mon Sep 17 00:00:00 2001 From: rajesh Date: Tue, 1 Jul 2025 18:15:28 +0530 Subject: [PATCH 04/75] Updated code --- .../tendermanagement/dao/AppointmentDao.java | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/AppointmentDao.java b/src/main/java/net/gepafin/tendermanagement/dao/AppointmentDao.java index 76a7fcff..ef5779fa 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/AppointmentDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/AppointmentDao.java @@ -154,6 +154,13 @@ public class AppointmentDao { ApplicationEntity oldApplication = Utils.getClonedEntityForData(application); NdgResponse ndgResponse = new NdgResponse(); + CompanyEntity company = companyService.validateCompany(application.getCompanyId()); + NdganagEntity ndganagEntity = ndganagRepository.findByVatNumber(company.getVatNumber()); + if (ndganagEntity != null && ndganagEntity.getNdg() != null) { + ndgResponse.setNdg(ndganagEntity.getNdg()); + return ndgResponse; + } + if (application.getNdgStatus() != null && application.getNdgStatus().equalsIgnoreCase(GepafinConstant.NDG_IN_PROGRESS)) { log.warn("NDG generation already in progress. applicationId: {}", applicationId); throw new CustomValidationException(Status.SUCCESS, Translator.toLocale(GepafinConstant.NDG_GENERATION_IS_IN_PROGRESS)); @@ -165,7 +172,7 @@ public class AppointmentDao { } // Update application status - log.info("Updating NDG status to IN_PROGRESS. applicationId: {}", applicationId); + log.info("Updating NDG status of applicationId: {}", applicationId); application.setNdgStatus(NdgStatusEnum.NDG_INITITATED.getValue()); applicationRepository.save(application); @@ -538,13 +545,9 @@ public class AppointmentDao { String authorizationToken = getBearerToken(hub); // Try retrieving NDG by VAT number - NdganagEntity ndganagEntity = ndganagRepository.findByVatNumber(company.getVatNumber()); AppointmentLoginResponse ndgResponse=new AppointmentLoginResponse(); - if (ndganagEntity != null || ndganagEntity.getNdg() != null) { - ndgResponse.setNdg(ndganagEntity.getNdg()); - }else { ndgResponse = retrieveNdgByVatNumber(company.getVatNumber(), authorizationToken, hub, application); - } + if (isNdgValid(ndgResponse.getNdg())) { saveNdg(application, company, ndgResponse.getNdg()); log.info("NDG successfully generated for applicationId: {}", applicationId); From b4831ce3486bc8f6b0eea7fa113a54028543464b Mon Sep 17 00:00:00 2001 From: rajesh Date: Wed, 2 Jul 2025 14:51:37 +0530 Subject: [PATCH 05/75] Update logic for csv extraction --- .../tendermanagement/dao/ApplicationDao.java | 109 +++++++++++------- .../dao/ApplicationEvaluationDao.java | 4 +- 2 files changed, 71 insertions(+), 42 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java index a90f9c4a..276c5c23 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java @@ -2423,61 +2423,90 @@ public class ApplicationDao { public byte[] downloadRankingCsv(Long callId) { CallEntity callEntity = callService.validateCall(callId); - BigDecimal scoreList = BigDecimal.ZERO; - List evaluationCriteriaEntities = - evaluationCriteriaRepository.findByCallIdAndIsDeletedFalse(callId); - List headers = Arrays.asList( - "ApplicationID", - "VatNumber", - "Company Name", - "Protocol", - "Requested Amount", - "Status", - "Total Score", - "Individual Scores" - ); + List applications = + applicationRepository.findByCallIdAndIsDeletedFalseAndStatusIn( + callId, + List.of( + ApplicationStatusForEvaluation.APPROVED.getValue(), + ApplicationStatusForEvaluation.ADMISSIBLE.getValue(), + ApplicationStatusForEvaluation.TECHNICAL_EVALUATION.getValue() + )); + List dynamicLabels = new ArrayList<>(); // Maintain insertion order, allow duplicates only once + Map> appLabelScoresMap = new HashMap<>(); - for (EvaluationCriteriaEntity evaluationCriteria : evaluationCriteriaEntities) { - scoreList = scoreList.add(evaluationCriteria.getScore()); + Map applicationMap = new HashMap<>(); + Map appTotalScoreMap = new HashMap<>(); + + for (ApplicationEntity app : applications) { + Long appId = app.getId(); + applicationMap.put(appId, app); + + ApplicationEvaluationEntity evaluation = + applicationEvaluationRepository.findByApplicationId(appId); + + BigDecimal totalScore = applicationEvaluationDao.calculateTotalScore(evaluation.getCriteria()); + appTotalScoreMap.put(appId, totalScore); + + List criteriaList = + evaluation.getCriteria() != null ? + Utils.convertJsonToList(evaluation.getCriteria(), new TypeReference>() {}) : + List.of(); + + List dbCriteriaList = applicationEvaluationDao.getCriteriaResponse(appId); + + Map scoreByLabel = new HashMap<>(); + + for (CriteriaResponse criteria : criteriaList) { + Optional matchedDb = dbCriteriaList.stream() + .filter(db -> Objects.equals(db.getId(), criteria.getId())) + .findFirst(); + + String label = matchedDb.map(CriteriaResponse::getLabel).orElse(""); + + if (!dynamicLabels.contains(label)) { + dynamicLabels.add(label); + } + + scoreByLabel.put(label, criteria.getScore() != null ? criteria.getScore() : BigDecimal.ZERO); + } + + appLabelScoresMap.put(appId, scoreByLabel); } - List applications = - applicationRepository.findByCallIdAndIsDeletedFalseAndStatusIn(callId,List.of(ApplicationStatusForEvaluation.APPROVED.getValue(),ApplicationStatusForEvaluation.ADMISSIBLE.getValue(),ApplicationStatusForEvaluation.TECHNICAL_EVALUATION.getValue())); + // Build headers dynamically + List headers = new ArrayList<>(List.of( + "ApplicationID", "VatNumber", "Company Name", "Protocol", "Requested Amount", "Status", "Total Score" + )); + headers.addAll(dynamicLabels); - // Collect all rows with totalScore for sorting + // Prepare data rows List> rows = new ArrayList<>(); for (ApplicationEntity app : applications) { + Long appId = app.getId(); CompanyEntity company = companyService.validateCompany(app.getCompanyId()); - String name = company.getCompanyName(); - String vat = company.getVatNumber(); - Long applicationId = app.getId(); ProtocolEntity protocolEntity = app.getProtocol(); - Long protocol = (protocolEntity != null) ? protocolEntity.getProtocolNumber() : 0L; - BigDecimal requestedAmount = app.getAmountRequested(); - String status = app.getStatus(); - ApplicationEvaluationEntity applicationEvaluationEntity = - applicationEvaluationRepository.findByApplicationId(app.getId()); + List row = new ArrayList<>(); + row.add(appId); + row.add(company.getVatNumber()); + row.add(company.getCompanyName()); + row.add(protocolEntity != null ? protocolEntity.getProtocolNumber() : 0L); + row.add(app.getAmountRequested()); + row.add(app.getStatus()); + row.add(appTotalScoreMap.get(appId)); - BigDecimal totalScore = applicationEvaluationDao.calculateTotalScore( - applicationEvaluationEntity.getCriteria() - ); + Map scores = appLabelScoresMap.getOrDefault(appId, Collections.emptyMap()); - rows.add(Arrays.asList( - applicationId, - vat, - name, - protocol, - requestedAmount, - status, - scoreList, - totalScore - )); + for (String label : dynamicLabels) { + row.add(scores.getOrDefault(label, BigDecimal.ZERO)); + } + + rows.add(row); } - // 5. Write the CSV using Commons CSV, with headers: + // Generate CSV ByteArrayOutputStream out = new ByteArrayOutputStream(); try (OutputStreamWriter writer = new OutputStreamWriter(out, StandardCharsets.UTF_8); CSVPrinter csvPrinter = new CSVPrinter(writer, diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java index ccc4e315..6d574394 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java @@ -1549,13 +1549,13 @@ public class ApplicationEvaluationDao { return callRepository.findCallEntityByApplicationId(applicationId); } - private List getEvaluationCriterias(CallEntity call) { + public List getEvaluationCriterias(CallEntity call) { log.info("Fetching evaluation criterias for callId: {}", call.getId()); return evaluationCriteriaRepository .findByCallIdAndLookupDataTypeAndIsDeletedFalse(call.getId(), LookUpDataEntity.LookUpDataTypeEnum.EVALUATION_CRITERIA.getValue()); } - private CriteriaResponse buildCriteriaResponse(Long applicationId, EvaluationCriteriaEntity criteria) { + public CriteriaResponse buildCriteriaResponse(Long applicationId, EvaluationCriteriaEntity criteria) { CriteriaResponse response = new CriteriaResponse(); response.setId(criteria.getId()); response.setLabel(criteria.getLookupData().getValue()); From e4cd66247eec37d676f147314e19836e172dd824 Mon Sep 17 00:00:00 2001 From: rajesh Date: Wed, 2 Jul 2025 19:11:07 +0530 Subject: [PATCH 06/75] Updated code for csv --- .../tendermanagement/dao/ApplicationDao.java | 50 +++++++++++++------ .../entities/ApplicationEntity.java | 3 ++ .../gepafin/tendermanagement/util/Utils.java | 35 +++++++++++-- .../db/changelog/db.changelog-1.0.0.xml | 6 +++ 4 files changed, 75 insertions(+), 19 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java index 276c5c23..3f829a92 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java @@ -63,6 +63,7 @@ import java.math.BigDecimal; import java.nio.charset.StandardCharsets; import java.sql.Timestamp; import java.text.MessageFormat; +import java.text.NumberFormat; import java.text.SimpleDateFormat; import java.time.LocalDate; import java.time.LocalDateTime; @@ -594,11 +595,9 @@ public class ApplicationDao { String fieldType = content.getName(); // Define handlers for different (fieldType + settingName) combinations - Map handlers = new HashMap<>(); // Add handler for isRequestedAmount if ("numberinput".equals(fieldType) && Boolean.TRUE.equals(settingMap.get("isRequestedAmount"))) { - handlers.put("isRequestedAmount", () -> { try { BigDecimal amountRequested = new BigDecimal(fieldValue.toString()); applicationFormEntity.getApplication().setAmountRequested(amountRequested); @@ -607,19 +606,20 @@ public class ApplicationDao { log.error("Invalid number format for requested amount: {}", fieldValue, e); throw new IllegalArgumentException("Field value is not a valid number: " + fieldValue, e); } - }); } // Add handler for isPecEmail if ("textinput".equals(fieldType) && Boolean.TRUE.equals(settingMap.get("isPecEmail"))) { - handlers.put("isPecEmail", () -> { applicationFormEntity.getApplication().setPecEmail(fieldValue.toString()); log.info("Set PEC to {} for Application ID: {}", fieldValue, applicationFormEntity.getApplication().getId()); - }); + } + + if ("textinput".equals(fieldType) && Boolean.TRUE.equals(settingMap.get("isPIVA"))) { + applicationFormEntity.getApplication().setVatNumber(fieldValue.toString()); + log.info("Set PEC to {} for Application ID: {}", fieldValue, applicationFormEntity.getApplication().getId()); } // Run all applicable handlers - handlers.values().forEach(Runnable::run); }); @@ -2433,10 +2433,11 @@ public class ApplicationDao { )); List dynamicLabels = new ArrayList<>(); // Maintain insertion order, allow duplicates only once - Map> appLabelScoresMap = new HashMap<>(); + Map> appLabelScoresMap = new HashMap<>(); Map applicationMap = new HashMap<>(); - Map appTotalScoreMap = new HashMap<>(); + Map appTotalScoreMap = new HashMap<>(); + Map appInstructorMap = new HashMap<>(); // New map to store instructor name per app for (ApplicationEntity app : applications) { Long appId = app.getId(); @@ -2445,8 +2446,19 @@ public class ApplicationDao { ApplicationEvaluationEntity evaluation = applicationEvaluationRepository.findByApplicationId(appId); + if (evaluation != null && evaluation.getAssignedApplicationsEntity() != null) { + Long userId = evaluation.getAssignedApplicationsEntity().getUserId(); + if (userId != null) { + userRepository.findById(userId).ifPresent(user -> { + String firstName = user.getFirstName() != null ? user.getFirstName() : ""; + String lastName = user.getLastName() != null ? user.getLastName() : ""; + appInstructorMap.put(appId, firstName + " " + lastName); + }); + } + } + BigDecimal totalScore = applicationEvaluationDao.calculateTotalScore(evaluation.getCriteria()); - appTotalScoreMap.put(appId, totalScore); + appTotalScoreMap.put(appId, Utils.convertToItalianFormatWithOnlyDecimalValue(String.valueOf(totalScore))); List criteriaList = evaluation.getCriteria() != null ? @@ -2455,7 +2467,7 @@ public class ApplicationDao { List dbCriteriaList = applicationEvaluationDao.getCriteriaResponse(appId); - Map scoreByLabel = new HashMap<>(); + Map scoreByLabel = new HashMap<>(); for (CriteriaResponse criteria : criteriaList) { Optional matchedDb = dbCriteriaList.stream() @@ -2467,8 +2479,9 @@ public class ApplicationDao { if (!dynamicLabels.contains(label)) { dynamicLabels.add(label); } + String criteriaScore= String.valueOf(criteria.getScore() != null ? criteria.getScore() : BigDecimal.ZERO); - scoreByLabel.put(label, criteria.getScore() != null ? criteria.getScore() : BigDecimal.ZERO); + scoreByLabel.put(label, Utils.convertToItalianFormatWithOnlyDecimalValue(criteriaScore)); } appLabelScoresMap.put(appId, scoreByLabel); @@ -2476,7 +2489,7 @@ public class ApplicationDao { // Build headers dynamically List headers = new ArrayList<>(List.of( - "ApplicationID", "VatNumber", "Company Name", "Protocol", "Requested Amount", "Status", "Total Score" + "ApplicationID","Application VatNumber", "VatNumber", "Company Name", "Protocol", "Requested Amount", "Status","Instructor Name", "Total Score" )); headers.addAll(dynamicLabels); @@ -2490,17 +2503,20 @@ public class ApplicationDao { List row = new ArrayList<>(); row.add(appId); + row.add(app.getVatNumber()); row.add(company.getVatNumber()); row.add(company.getCompanyName()); row.add(protocolEntity != null ? protocolEntity.getProtocolNumber() : 0L); - row.add(app.getAmountRequested()); + String formattedAmount=Utils.convertToItalianFormatWithOnlyDecimalValue(String.valueOf(app.getAmountRequested())); + row.add(formattedAmount); row.add(app.getStatus()); + row.add(appInstructorMap.getOrDefault(appId, "")); row.add(appTotalScoreMap.get(appId)); - Map scores = appLabelScoresMap.getOrDefault(appId, Collections.emptyMap()); + Map scores = appLabelScoresMap.getOrDefault(appId, Collections.emptyMap()); for (String label : dynamicLabels) { - row.add(scores.getOrDefault(label, BigDecimal.ZERO)); + row.add(scores.getOrDefault(label, "")); } rows.add(row); @@ -2510,7 +2526,9 @@ public class ApplicationDao { ByteArrayOutputStream out = new ByteArrayOutputStream(); try (OutputStreamWriter writer = new OutputStreamWriter(out, StandardCharsets.UTF_8); CSVPrinter csvPrinter = new CSVPrinter(writer, - CSVFormat.DEFAULT.withHeader(headers.toArray(new String[0])))) { + CSVFormat.DEFAULT + .withDelimiter(';') + .withHeader(headers.toArray(new String[0])))) { for (List row : rows) { csvPrinter.printRecord(row); diff --git a/src/main/java/net/gepafin/tendermanagement/entities/ApplicationEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/ApplicationEntity.java index 8e783c70..dacc3541 100644 --- a/src/main/java/net/gepafin/tendermanagement/entities/ApplicationEntity.java +++ b/src/main/java/net/gepafin/tendermanagement/entities/ApplicationEntity.java @@ -76,4 +76,7 @@ public class ApplicationEntity extends BaseEntity { @Column(name = "PEC_EMAIL") private String pecEmail; + @Column(name="VAT_NUMBER") + private String vatNumber; + } \ No newline at end of file diff --git a/src/main/java/net/gepafin/tendermanagement/util/Utils.java b/src/main/java/net/gepafin/tendermanagement/util/Utils.java index 19feb0e2..13cf6e87 100644 --- a/src/main/java/net/gepafin/tendermanagement/util/Utils.java +++ b/src/main/java/net/gepafin/tendermanagement/util/Utils.java @@ -6,9 +6,7 @@ import java.lang.reflect.Type; import java.nio.charset.StandardCharsets; import java.security.SecureRandom; import java.sql.Timestamp; -import java.text.NumberFormat; -import java.text.ParseException; -import java.text.SimpleDateFormat; +import java.text.*; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.OffsetDateTime; @@ -1063,6 +1061,37 @@ public class Utils { ServletRequestAttributes attributes = new ServletRequestAttributes(mockRequest); RequestContextHolder.setRequestAttributes(attributes, true); } + public static String convertToItalianFormatWithOnlyDecimalValue(String amount) { + try { + // Step 1: Sanitize and standardize the input + String sanitizedAmount = amount.trim(); + + // Remove thousand separators (either . or , depending on input style) + sanitizedAmount = sanitizedAmount.replace(",", "").replace(" ", ""); + + // Step 2: Ensure it uses '.' as decimal separator for parsing + if (sanitizedAmount.contains(".")) { + // It already uses dot as decimal separator + } else if (sanitizedAmount.contains(",")) { + // If input uses comma as decimal separator (like "1234,56") + sanitizedAmount = sanitizedAmount.replace(",", "."); + } + + // Step 3: Parse to double + double parsedAmount = Double.parseDouble(sanitizedAmount); + + // Step 4: Format without thousand separator and with comma as decimal + DecimalFormatSymbols symbols = new DecimalFormatSymbols(); + symbols.setDecimalSeparator(','); + + DecimalFormat italianDecimalFormat = new DecimalFormat("0.00", symbols); + italianDecimalFormat.setGroupingUsed(false); // no thousand separator + + return italianDecimalFormat.format(parsedAmount); + } catch (NumberFormatException e) { + return "Invalid amount format"; + } + } } 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 c16d810c..28f5c17a 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 @@ -2984,4 +2984,10 @@ + + + + + + From cbd06770fd40e95107735cb25acfee7ffd107980 Mon Sep 17 00:00:00 2001 From: rajesh Date: Thu, 3 Jul 2025 15:01:31 +0530 Subject: [PATCH 07/75] Added field pec in csv --- .../gepafin/tendermanagement/dao/ApplicationDao.java | 12 +++++++++--- .../service/impl/ApplicationServiceImpl.java | 2 +- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java index 3f829a92..0564ad66 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java @@ -219,6 +219,9 @@ public class ApplicationDao { @Autowired private EvaluationCriteriaRepository evaluationCriteriaRepository; + @Autowired + private CallRepository callRepository; + public final Random random = new Random(); public ApplicationResponseBean createApplication(HttpServletRequest request, ApplicationRequestBean applicationRequestBean, Long formId, Long applicationId) { @@ -2420,8 +2423,9 @@ public class ApplicationDao { emailNotificationDao.sendMail(hub.getId(), subject, body, List.of(GepafinConstant.RINALDO_EMAIL),emailLogRequest); } - public byte[] downloadRankingCsv(Long callId) { - CallEntity callEntity = callService.validateCall(callId); + public byte[] downloadRankingCsv(Long callId,UserEntity userEntity) { + + CallEntity callEntity = validator.validateUserWithCall(userEntity,callId); List applications = applicationRepository.findByCallIdAndIsDeletedFalseAndStatusIn( @@ -2489,7 +2493,7 @@ public class ApplicationDao { // Build headers dynamically List headers = new ArrayList<>(List.of( - "ApplicationID","Application VatNumber", "VatNumber", "Company Name", "Protocol", "Requested Amount", "Status","Instructor Name", "Total Score" + "ApplicationID","Application VatNumber", "VatNumber", "Company Name", "Protocol", "Requested Amount", "Status","Instructor Name","Application PEC","Company PEC","Total Score" )); headers.addAll(dynamicLabels); @@ -2511,6 +2515,8 @@ public class ApplicationDao { row.add(formattedAmount); row.add(app.getStatus()); row.add(appInstructorMap.getOrDefault(appId, "")); + row.add(app.getPecEmail()); + row.add(company.getPec()); row.add(appTotalScoreMap.get(appId)); Map scores = appLabelScoresMap.getOrDefault(appId, Collections.emptyMap()); diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationServiceImpl.java index aca38d23..e311340e 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationServiceImpl.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationServiceImpl.java @@ -180,6 +180,6 @@ public class ApplicationServiceImpl implements ApplicationService { @Override public byte[] downloadRankingCsv(HttpServletRequest request, Long callId) { UserEntity userEntity = validator.validateUser(request); - return applicationDao.downloadRankingCsv(callId); + return applicationDao.downloadRankingCsv(callId,userEntity); } } From f1aadafa1a0faa24498bc5b136d674765bb28feb Mon Sep 17 00:00:00 2001 From: rajesh Date: Thu, 3 Jul 2025 17:28:53 +0530 Subject: [PATCH 08/75] Done ticket GEPAFINBE-233 --- .../net/gepafin/tendermanagement/dao/ApplicationDao.java | 8 +++++--- .../java/net/gepafin/tendermanagement/dao/CallDao.java | 7 +++++++ .../net/gepafin/tendermanagement/entities/CallEntity.java | 3 +++ .../model/request/CreateCallRequestStep1.java | 2 ++ .../model/request/UpdateCallRequestStep1.java | 2 ++ .../model/response/CallDetailsResponseBean.java | 2 ++ .../tendermanagement/model/response/CallResponse.java | 2 ++ src/main/resources/db/changelog/db.changelog-1.0.0.xml | 6 ++++++ 8 files changed, 29 insertions(+), 3 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java index 276c5c23..e46e6979 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java @@ -989,10 +989,12 @@ public class ApplicationDao { // call = callService.validatePublishedCall(call.getId()); // checkIfApplicationExists(call, userWithCompanyEntity, userEntity); HubEntity hubEntity = hubService.valdateHub(call.getHub().getId()); - if(hubEntity.getUniqueUuid().equals(defaultHubUuid)){ - checkIfApplicationExists(call, userWithCompanyEntity, userEntity); + if(call.getAllowMultipleApplications() == null || Boolean.FALSE.equals(call.getAllowMultipleApplications())){ + if(hubEntity.getUniqueUuid().equals(defaultHubUuid)){ + checkIfApplicationExists(call, userWithCompanyEntity, userEntity); + } } - ApplicationEntity applicationEntity = createApplicationEntity(userEntity, call, userWithCompanyEntity); + ApplicationEntity applicationEntity = createApplicationEntity(userEntity, call, userWithCompanyEntity); applicationEntity.setComments(applicationRequest.getComments()); applicationEntity = saveApplicationEntity(applicationEntity); return getApplicationResponse(applicationEntity); diff --git a/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java b/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java index 94c6f912..509e9e51 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java @@ -224,6 +224,10 @@ public class CallDao { callEntity.setHub(userEntity.getHub()); callEntity.setNumberOfCheck(createCallRequest.getNumberOfCheck()); callEntity.setAppointmentTemplateId(createCallRequest.getAppointmentTemplateId()); + callEntity.setAllowMultipleApplications(false); + if (createCallRequest.getAllowMultipleApplications() != null) { + callEntity.setAllowMultipleApplications(createCallRequest.getAllowMultipleApplications()); + } callEntity = callRepository.save(callEntity); log.info("CallEntity saved with ID: {} for call name: '{}'", callEntity.getId(), callEntity.getName()); @@ -406,6 +410,7 @@ public class CallDao { createCallResponseBean.setDocumentationRequested(callEntity.getDocumentationRequested()); createCallResponseBean.setPriorityArea(callEntity.getPriorityArea()); createCallResponseBean.setConfidi(callEntity.getConfidi()); + createCallResponseBean.setAllowMultipleApplications(callEntity.getAllowMultipleApplications()); createCallResponseBean.setAmountMin(callEntity.getAmountMin()); createCallResponseBean.setPhoneNumber(callEntity.getPhoneNumber()); createCallResponseBean.setEndTime(callEntity.getEndTime()); @@ -683,6 +688,7 @@ public class CallDao { setIfUpdated(callEntity::getEvaluationVersion, callEntity::setEvaluationVersion, updateCallRequest.getEvaluationVersion().getValue()); setIfUpdated(callEntity::getNumberOfCheck, callEntity::setNumberOfCheck, updateCallRequest.getNumberOfCheck()); setIfUpdated(callEntity::getAppointmentTemplateId, callEntity::setAppointmentTemplateId, updateCallRequest.getAppointmentTemplateId()); + setIfUpdated(callEntity::getAllowMultipleApplications, callEntity::setAllowMultipleApplications, updateCallRequest.getAllowMultipleApplications()); callEntity = callRepository.save(callEntity); /** This code is responsible for adding a version history log for the "update call step 1" operation **/ @@ -792,6 +798,7 @@ public class CallDao { callDetailsResponseBean.setUpdatedDate(callEntity.getUpdatedDate()); callDetailsResponseBean.setNumberOfCheck(callEntity.getNumberOfCheck()); callDetailsResponseBean.setAppointmentTemplateId(callEntity.getAppointmentTemplateId()); + callDetailsResponseBean.setAllowMultipleApplications(callEntity.getAllowMultipleApplications()); return callDetailsResponseBean; } diff --git a/src/main/java/net/gepafin/tendermanagement/entities/CallEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/CallEntity.java index dc8c05d8..dd2655ed 100644 --- a/src/main/java/net/gepafin/tendermanagement/entities/CallEntity.java +++ b/src/main/java/net/gepafin/tendermanagement/entities/CallEntity.java @@ -99,5 +99,8 @@ public class CallEntity extends BaseEntity { @Column(name = "APPOINTMENT_TEMPLATE_ID") private Long appointmentTemplateId; + + @Column(name = "allow_multiple_applications") + private Boolean allowMultipleApplications; } diff --git a/src/main/java/net/gepafin/tendermanagement/model/request/CreateCallRequestStep1.java b/src/main/java/net/gepafin/tendermanagement/model/request/CreateCallRequestStep1.java index 7d4bf8cf..c364db5a 100644 --- a/src/main/java/net/gepafin/tendermanagement/model/request/CreateCallRequestStep1.java +++ b/src/main/java/net/gepafin/tendermanagement/model/request/CreateCallRequestStep1.java @@ -44,6 +44,8 @@ public class CreateCallRequestStep1 { private Boolean confidi; + private Boolean allowMultipleApplications; + private List faq; private EvaluationVersionEnum evaluationVersion; diff --git a/src/main/java/net/gepafin/tendermanagement/model/request/UpdateCallRequestStep1.java b/src/main/java/net/gepafin/tendermanagement/model/request/UpdateCallRequestStep1.java index 01a0ea39..30530381 100644 --- a/src/main/java/net/gepafin/tendermanagement/model/request/UpdateCallRequestStep1.java +++ b/src/main/java/net/gepafin/tendermanagement/model/request/UpdateCallRequestStep1.java @@ -38,6 +38,8 @@ public class UpdateCallRequestStep1 { private Boolean confidi; + private Boolean allowMultipleApplications; + private List faq; private Long numberOfCheck; diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/CallDetailsResponseBean.java b/src/main/java/net/gepafin/tendermanagement/model/response/CallDetailsResponseBean.java index 7ee0b620..51dbdd4d 100644 --- a/src/main/java/net/gepafin/tendermanagement/model/response/CallDetailsResponseBean.java +++ b/src/main/java/net/gepafin/tendermanagement/model/response/CallDetailsResponseBean.java @@ -23,6 +23,8 @@ public class CallDetailsResponseBean { private Boolean confidi; + private Boolean allowMultipleApplications; + private CallStatusEnum status; private Long regionId; diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/CallResponse.java b/src/main/java/net/gepafin/tendermanagement/model/response/CallResponse.java index 76289b06..13a90715 100644 --- a/src/main/java/net/gepafin/tendermanagement/model/response/CallResponse.java +++ b/src/main/java/net/gepafin/tendermanagement/model/response/CallResponse.java @@ -44,6 +44,8 @@ public class CallResponse { private Boolean confidi; + private Boolean allowMultipleApplications; + private BigDecimal amountMin; private String email; 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 c16d810c..39f73ce4 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 @@ -2984,4 +2984,10 @@ + + + + + + From 2a75dadba920fc61bbb6c1f4ccb80d941a8b59f8 Mon Sep 17 00:00:00 2001 From: rajesh Date: Tue, 8 Jul 2025 19:31:24 +0530 Subject: [PATCH 09/75] Done ticket GEPAFINBE-234 --- .../dao/AssignedApplicationsDao.java | 1 + .../entities/ApplicationFormView.java | 3 + .../entities/AssignedApplicationsView.java | 3 + .../AssignedApplicationViewResponse.java | 1 + .../db/changelog/db.changelog-1.0.0.xml | 8 ++ ...pdate_application_form_view_08_07_2025.sql | 105 ++++++++++++++++++ ...e_assigned_application_view_08_07_2025.sql | 62 +++++++++++ 7 files changed, 183 insertions(+) create mode 100644 src/main/resources/db/dump/update_application_form_view_08_07_2025.sql create mode 100644 src/main/resources/db/dump/update_assigned_application_view_08_07_2025.sql diff --git a/src/main/java/net/gepafin/tendermanagement/dao/AssignedApplicationsDao.java b/src/main/java/net/gepafin/tendermanagement/dao/AssignedApplicationsDao.java index c05b04c2..0df566f5 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/AssignedApplicationsDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/AssignedApplicationsDao.java @@ -491,6 +491,7 @@ public class AssignedApplicationsDao { response.setCreatedDate(view.getCreatedDate()); response.setUpdatedDate(view.getUpdatedDate()); response.setEmailSendResponse(view.getEmailSendResponse()); + response.setAssignedUserName(view.getAssignedUserName()); return response; } diff --git a/src/main/java/net/gepafin/tendermanagement/entities/ApplicationFormView.java b/src/main/java/net/gepafin/tendermanagement/entities/ApplicationFormView.java index b3733afc..0af565bf 100644 --- a/src/main/java/net/gepafin/tendermanagement/entities/ApplicationFormView.java +++ b/src/main/java/net/gepafin/tendermanagement/entities/ApplicationFormView.java @@ -115,4 +115,7 @@ public class ApplicationFormView { @Column(name = "call_start_time") private LocalTime callStartTime; + @Column(name = "INSTRUCTOR_NAME") + private String instructorName; + } diff --git a/src/main/java/net/gepafin/tendermanagement/entities/AssignedApplicationsView.java b/src/main/java/net/gepafin/tendermanagement/entities/AssignedApplicationsView.java index 46bf004b..e4224631 100644 --- a/src/main/java/net/gepafin/tendermanagement/entities/AssignedApplicationsView.java +++ b/src/main/java/net/gepafin/tendermanagement/entities/AssignedApplicationsView.java @@ -67,4 +67,7 @@ public class AssignedApplicationsView{ @Column(name = "HUB_ID") private Long hubId; + + @Column(name="ASSIGNED_USER_NAME") + private String assignedUserName; } diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/AssignedApplicationViewResponse.java b/src/main/java/net/gepafin/tendermanagement/model/response/AssignedApplicationViewResponse.java index e9a1f9f5..22f00b0d 100644 --- a/src/main/java/net/gepafin/tendermanagement/model/response/AssignedApplicationViewResponse.java +++ b/src/main/java/net/gepafin/tendermanagement/model/response/AssignedApplicationViewResponse.java @@ -21,6 +21,7 @@ public class AssignedApplicationViewResponse extends BaseBean { private Long protocolNumber; private String callName; private String companyName; + private String assignedUserName; private List emailSendResponse; 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 f459961b..ef0f3447 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 @@ -2996,4 +2996,12 @@ + + + + + + diff --git a/src/main/resources/db/dump/update_application_form_view_08_07_2025.sql b/src/main/resources/db/dump/update_application_form_view_08_07_2025.sql new file mode 100644 index 00000000..e68f0b60 --- /dev/null +++ b/src/main/resources/db/dump/update_application_form_view_08_07_2025.sql @@ -0,0 +1,105 @@ + +DROP VIEW IF EXISTS gepafin_schema.application_form_view ; + +CREATE OR REPLACE VIEW gepafin_schema.application_form_view AS +SELECT app_data.id, + app_data.call_id, + app_data.application_form_id, + app_data.form_id, + app_data.application_id, + field_data.value ->> 'id'::text AS field_id, + COALESCE(( SELECT s.value ->> 'value'::text + FROM jsonb_array_elements(field_data.value -> 'settings'::text) s(value) + WHERE (s.value ->> 'name'::text) = 'label'::text + LIMIT 1), field_data.value ->> 'label'::text) AS field_label, + ( SELECT (s.value ->> 'value'::text)::boolean AS bool + FROM jsonb_array_elements(field_data.value -> 'settings'::text) s(value) + WHERE (s.value ->> 'name'::text) = 'reportEnable'::text + LIMIT 1) AS report_enable, + COALESCE(( SELECT s.value ->> 'value'::text + FROM jsonb_array_elements(field_data.value -> 'settings'::text) s(value) + WHERE (s.value ->> 'name'::text) = 'reportHeader'::text + LIMIT 1), field_data.value ->> 'reportHeader'::text) AS report_header, + field_data.value ->> 'name'::text AS field_type, + CASE + WHEN (field_data.value ->> 'name'::text) = 'fileupload'::text THEN to_jsonb(( SELECT string_agg(d.file_name::text, ', '::text) AS string_agg + FROM unnest(string_to_array(app_data.field_value, ','::text)) file_ids(file_id) + JOIN gepafin_schema.document d ON d.id::text = file_ids.file_id + WHERE d.is_deleted = false)) + WHEN (field_data.value ->> 'name'::text) = ANY (ARRAY['checkboxes'::text, 'select'::text, 'radio'::text]) THEN + CASE + WHEN app_data.field_value ~~ '[%'::text THEN to_jsonb(( SELECT string_agg(opt.value ->> 'label'::text, ', '::text) AS string_agg + FROM jsonb_array_elements_text(app_data.field_value::jsonb) selected_id(value) + CROSS JOIN LATERAL ( SELECT s.value + FROM jsonb_array_elements(field_data.value -> 'settings'::text) s(value) + WHERE (s.value ->> 'name'::text) = 'options'::text) options_setting, + LATERAL jsonb_array_elements(options_setting.value -> 'value'::text) opt(value) + WHERE (opt.value ->> 'name'::text) = selected_id.value)) + ELSE to_jsonb(( SELECT opt.value ->> 'label'::text + FROM ( SELECT s.value + FROM jsonb_array_elements(field_data.value -> 'settings'::text) s(value) + WHERE (s.value ->> 'name'::text) = 'options'::text) options_setting, + LATERAL jsonb_array_elements(options_setting.value -> 'value'::text) opt(value) + WHERE (opt.value ->> 'name'::text) = app_data.field_value + LIMIT 1)) + END + ELSE to_jsonb(app_data.field_value) + END AS field_value, + app_data.status, + app_data.amount_requested, + app_data.amount_accepted, + app_data.is_deleted, + app_data.hub_id, + app_data.user_id, + app_data.evaluation_version, + app_data.company_id, + c.company_name, + c.vat_number AS company_vat_number, + c.codice_ateco, + c.codice_fiscale AS company_codice_fiscale, + p.protocol_number, + b.codice_fiscale AS user_codice_fiscale, + COALESCE(NULLIF(TRIM(BOTH FROM concat(COALESCE(u.first_name, ''::character varying), ' ', COALESCE(u.last_name, ''::character varying))), ''::text), ''::text) AS user_name, + COALESCE( NULLIF(TRIM(BOTH FROM CONCAT(COALESCE(aauser.first_name, ''), ' ', COALESCE(aauser.last_name, ''))),''),'NA') AS instructor_name, + uwc.is_legal_representant AS legal_representative, + cl.name AS call_title, + cl.end_date AS call_end_date, + cl.end_time AS call_end_time, + cl.start_date AS call_start_date, + cl.start_time AS call_start_time + FROM ( SELECT a.id AS application_id, + a.call_id, + a.protocol_number, + af.id AS application_form_id, + af.form_id, + aff.id, + aff.field_value, + a.status, + a.amount_requested, + a.amount_accepted, + a.is_deleted, + a.hub_id, + a.user_id, + a.evaluation_version, + a.created_date, + a.company_id, + aff.field_id, + f.content + FROM gepafin_schema.application a + JOIN gepafin_schema.application_form af ON af.application_id = a.id + JOIN gepafin_schema.application_form_field aff ON aff.application_form_id = af.id + JOIN gepafin_schema.form f ON f.id = af.form_id + WHERE a.is_deleted = false) app_data + CROSS JOIN LATERAL ( SELECT jsonb_array_elements.value + FROM jsonb_array_elements(app_data.content::jsonb) jsonb_array_elements(value) + WHERE (jsonb_array_elements.value ->> 'id'::text) = app_data.field_id::text) field_data(value) + LEFT JOIN gepafin_schema.call cl ON app_data.call_id = cl.id + LEFT JOIN gepafin_schema.company c ON app_data.company_id = c.id + LEFT JOIN gepafin_schema.protocol p ON app_data.protocol_number = p.id + LEFT JOIN gepafin_schema.gepafin_user u ON app_data.user_id = u.id + LEFT JOIN gepafin_schema.user_with_company uwc ON app_data.user_id = uwc.user_id AND app_data.company_id = uwc.company_id AND uwc.is_deleted = false + LEFT JOIN gepafin_schema.beneficiary b ON u.beneficiary_id = b.id + LEFT JOIN gepafin_schema.assigned_applications aa ON app_data.application_id = aa.application_id + LEFT JOIN gepafin_schema.gepafin_user aauser ON aa.user_id = aauser.id + WHERE app_data.id IS NOT NULL AND (app_data.status::text <> ALL (ARRAY['DRAFT'::character varying::text, 'AWAITING'::character varying::text, 'READY'::character varying::text])) + ORDER BY app_data.id, (field_data.value ->> 'id'::text); \ No newline at end of file diff --git a/src/main/resources/db/dump/update_assigned_application_view_08_07_2025.sql b/src/main/resources/db/dump/update_assigned_application_view_08_07_2025.sql new file mode 100644 index 00000000..354ab8c5 --- /dev/null +++ b/src/main/resources/db/dump/update_assigned_application_view_08_07_2025.sql @@ -0,0 +1,62 @@ + +DROP VIEW IF EXISTS gepafin_schema.assigned_applications_view ; + +CREATE OR REPLACE VIEW gepafin_schema.assigned_applications_view AS +SELECT + -- From assigned_applications + aa.id AS id, + aa.user_id AS user_id, + aa.status AS status, + aa.created_date AS created_date, + aa.updated_date AS updated_date, + aa.is_deleted AS is_deleted, + + -- From application + a.id AS application_id, + a.hub_id as hub_id, + a.status AS application_status, + a.submission_date AS submission_date, + ae.end_date AS evaluation_end_date, + a.ndg AS ndg, + a.appointment_id AS appointment_id, + + -- From protocol (OneToOne) + p.protocol_number AS protocol_number, + + -- From call (ManyToOne) + cl.name AS call_name, + + -- From company (ManyToOne) + c.company_name AS company_name, + ae.email_send_response AS email_send_response, + COALESCE(NULLIF(TRIM(BOTH FROM concat(COALESCE(u.first_name, ''::character varying), ' ', COALESCE(u.last_name, ''::character varying))), ''::text), ''::text) AS assigned_user_name + + +FROM gepafin_schema.assigned_applications aa + +-- Join application (ManyToOne from assigned_applications) +LEFT JOIN gepafin_schema.application a + ON aa.application_id = a.id + AND (a.is_deleted IS FALSE OR a.is_deleted IS NULL) + +-- Join application_evaluation (application_id matches + not deleted) +LEFT JOIN gepafin_schema.application_evaluation ae + ON ae.application_id = a.id + AND (ae.is_deleted IS FALSE OR ae.is_deleted IS NULL) + +-- Join protocol (OneToOne from application) +LEFT JOIN gepafin_schema.protocol p + ON a.protocol_number = p.id + +-- Join call (ManyToOne from application) +LEFT JOIN gepafin_schema.call cl + ON a.call_id = cl.id + +-- Join company (ManyToOne from application) +LEFT JOIN gepafin_schema.company c + ON a.company_id = c.id + +LEFT JOIN gepafin_schema.gepafin_user u ON aa.user_id = u.id + + +WHERE aa.is_deleted IS FALSE OR aa.is_deleted IS NULL; From ad26599d48a95415654dd617d07a358e240b055a Mon Sep 17 00:00:00 2001 From: rajesh Date: Thu, 10 Jul 2025 20:31:41 +0530 Subject: [PATCH 10/75] Fixed call end date issue --- .../constants/GepafinConstant.java | 2 + .../gepafin/tendermanagement/dao/CallDao.java | 49 ++++++++++++++----- src/main/resources/message_en.properties | 2 + src/main/resources/message_it.properties | 2 + 4 files changed, 42 insertions(+), 13 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java b/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java index 42857d23..71c63a9f 100644 --- a/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java +++ b/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java @@ -575,6 +575,8 @@ public class GepafinConstant { public static final String NDG_NOT_FOUND="ndg.not.found"; public static final String EMAIL_PEC_REQUIRED="email.pec.cannot.null"; public static final String USER_REQUEST_COMPLETED="user.request.completed"; + public static final String END_DATE_GREATER_THAN_NOW="end.date.greater.than.now"; + } diff --git a/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java b/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java index 509e9e51..d0bef93e 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java @@ -628,19 +628,19 @@ public class CallDao { if (dates.size() > 0) { setIfUpdated(callEntity::getStartDate, callEntity::setStartDate, dates.get(0)); } - if (dates.size() > 1) { - LocalDate requestEndDate = dates.get(1).toLocalDate(); // Extract only the date - LocalDate storedEndDate = callEntity.getEndDate().toLocalDate(); // Extract only the date - - if (!requestEndDate.equals(storedEndDate)) { // Check if dates are different - - setIfUpdated(callEntity::getEndDate, callEntity::setEndDate, dates.get(1)); -// callEntity.setStatus(CallStatusEnum.PUBLISH.getValue()); -// callRepository.save(callEntity); - isEndDateUpdated = true; - } - } - } +// if (dates.size() > 1) { +// LocalDate requestEndDate = dates.get(1).toLocalDate(); // Extract only the date +// LocalDate storedEndDate = callEntity.getEndDate().toLocalDate(); // Extract only the date +// +// if (!requestEndDate.equals(storedEndDate)) { // Check if dates are different +// +// setIfUpdated(callEntity::getEndDate, callEntity::setEndDate, dates.get(1)); +//// callEntity.setStatus(CallStatusEnum.PUBLISH.getValue()); +//// callRepository.save(callEntity); +// isEndDateUpdated = true; +// } +// } +// } if (updateCallRequest.getEndTime() != null) { LocalTime requestEndTime = DateTimeUtil.parseTime(updateCallRequest.getEndTime()); @@ -653,6 +653,29 @@ public class CallDao { isEndTimeUpdated = true; } } + if (dates.size() > 1) { + LocalDate requestEndDate = dates.get(1).toLocalDate(); // Extract only the date + LocalDate storedEndDate = callEntity.getEndDate().toLocalDate(); // Extract only the date + + if (!requestEndDate.equals(storedEndDate)) { + // Check if dates are different + + setIfUpdated(callEntity::getEndDate, callEntity::setEndDate, dates.get(1)); + if(callEntity.getStatus().equals(CallStatusEnum.EXPIRED.getValue())) { + LocalDateTime newEndDate = LocalDateTime.of(requestEndDate, callEntity.getEndTime()); + if(newEndDate.isBefore(LocalDateTime.now())){ + throw new CustomValidationException(Status.VALIDATION_ERROR,Translator.toLocale(GepafinConstant.END_DATE_GREATER_THAN_NOW)); + } + + if (requestEndDate.isAfter(LocalDate.now()) || requestEndDate.isEqual(LocalDate.now())) { + callEntity.setStatus(CallStatusEnum.PUBLISH.getValue()); + callRepository.save(callEntity); + } + } + isEndDateUpdated = true; + } + } + } if (isEndDateUpdated || isEndTimeUpdated) { callRepository.save(callEntity); loggingUtil.logUserAction(UserActionRequest.builder() diff --git a/src/main/resources/message_en.properties b/src/main/resources/message_en.properties index a706e568..ad25a88b 100644 --- a/src/main/resources/message_en.properties +++ b/src/main/resources/message_en.properties @@ -411,3 +411,5 @@ user.action.id.not.found = User Action id not found. ndg.not.found=NDG not found. email.pec.cannot.null=Email pec is required. user.request.completed=User request completed successfully. +end.date.greater.than.now=End date must be greater than the current date and time. + diff --git a/src/main/resources/message_it.properties b/src/main/resources/message_it.properties index f4246425..f98e55b8 100644 --- a/src/main/resources/message_it.properties +++ b/src/main/resources/message_it.properties @@ -402,3 +402,5 @@ user.action.id.not.found = ID azione utente non trovato. ndg.not.found=NDG non trovato. email.pec.cannot.null=L'indirizzo email pec obbligatorio. user.request.completed=Richiesta utente completata con successo. +end.date.greater.than.now=La data di fine deve essere successiva alla data e all'ora correnti. + From 107d1da6e1e358e08c385a9f8ee5cd9139d7d8f4 Mon Sep 17 00:00:00 2001 From: rajesh Date: Mon, 14 Jul 2025 12:09:26 +0530 Subject: [PATCH 11/75] Done ticket GEPAFINBE-232 --- .../dao/ApplicationAmendmentRequestDao.java | 2 +- .../dao/ApplicationEvaluationDao.java | 2 +- .../tendermanagement/dao/DocumentDao.java | 98 +++++++++++++++++-- 3 files changed, 91 insertions(+), 11 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java index 2882dc7f..68d67983 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java @@ -803,7 +803,7 @@ public class ApplicationAmendmentRequestDao { } - private List getApplicationFormFieldList( + public List getApplicationFormFieldList( ApplicationAmendmentRequestEntity applicationAmendment, List fieldIds) { List applicationFormList = applicationFormRepository diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java index 9fa68a28..91e7b8b3 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java @@ -1155,7 +1155,7 @@ public class ApplicationEvaluationDao { applicationEvaluationResponse.setEmailSendResponse(entity.getEmailSendResponse()); return applicationEvaluationResponse; } - private List prepareEvaluationDocumentBeanList(ApplicationEvaluationEntity entity) { + public List prepareEvaluationDocumentBeanList(ApplicationEvaluationEntity entity) { List docRequest = new ArrayList<>(); if (entity != null && entity.getEvaluationDocument() != null) { diff --git a/src/main/java/net/gepafin/tendermanagement/dao/DocumentDao.java b/src/main/java/net/gepafin/tendermanagement/dao/DocumentDao.java index 3b5b41f6..013bf9e5 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/DocumentDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/DocumentDao.java @@ -1,13 +1,19 @@ package net.gepafin.tendermanagement.dao; import lombok.extern.slf4j.Slf4j; +import java.util.*; +import java.util.function.Function; import java.util.stream.Collectors; import jakarta.servlet.http.HttpServletRequest; +import net.gepafin.tendermanagement.entities.*; import net.gepafin.tendermanagement.enums.*; +import net.gepafin.tendermanagement.model.request.AmendmentFormField; +import net.gepafin.tendermanagement.model.request.EvaluationDocumentRequest; import net.gepafin.tendermanagement.model.request.VersionHistoryRequest; -import net.gepafin.tendermanagement.repositories.ApplicationEvaluationRepository; -import net.gepafin.tendermanagement.repositories.ApplicationRepository; +import net.gepafin.tendermanagement.model.response.ContentResponseBean; +import net.gepafin.tendermanagement.model.response.SettingResponseBean; +import net.gepafin.tendermanagement.repositories.*; import net.gepafin.tendermanagement.util.LoggingUtil; import net.gepafin.tendermanagement.util.Utils; import net.gepafin.tendermanagement.web.rest.api.errors.CustomValidationException; @@ -17,13 +23,8 @@ import org.springframework.web.multipart.MultipartFile; import net.gepafin.tendermanagement.config.Translator; import net.gepafin.tendermanagement.constants.GepafinConstant; -import net.gepafin.tendermanagement.entities.ApplicationEntity; -import net.gepafin.tendermanagement.entities.CallEntity; -import net.gepafin.tendermanagement.entities.DocumentEntity; import net.gepafin.tendermanagement.model.response.DocumentResponseBean; import net.gepafin.tendermanagement.model.response.UploadFileOnAmazonS3Response; -import net.gepafin.tendermanagement.repositories.ApplicationAmendmentRequestRepository; -import net.gepafin.tendermanagement.repositories.DocumentRepository; import net.gepafin.tendermanagement.service.AmazonS3Service; import net.gepafin.tendermanagement.service.ApplicationAmendmentRequestService; import net.gepafin.tendermanagement.service.ApplicationService; @@ -31,8 +32,6 @@ import net.gepafin.tendermanagement.service.CallService; import net.gepafin.tendermanagement.web.rest.api.errors.ResourceNotFoundException; import net.gepafin.tendermanagement.web.rest.api.errors.Status; import org.springframework.beans.factory.annotation.Value; -import java.util.ArrayList; -import java.util.List; @Slf4j @@ -78,6 +77,18 @@ public class DocumentDao { @Autowired private HttpServletRequest request; + @Autowired + private ApplicationFormRepository applicationFormRepository; + + @Autowired + private ApplicationFormFieldRepository applicationFormFieldRepository; + + @Autowired + private ApplicationAmendmentRequestDao applicationAmendmentRequestDao; + + @Autowired + private ApplicationEvaluationDao applicationEvaluationDao; + // @Value("${aws.s3.url.folder}") // private String s3Folder; @@ -224,18 +235,72 @@ public class DocumentDao { } else if (DocumentSourceTypeEnum.APPLICATION.getValue().equalsIgnoreCase(documentEntity.getSource())) { applicationId = documentEntity.getSourceId(); ApplicationEntity applicationEntity = applicationService.validateApplication(applicationId); + + List applicationFormEntity=applicationFormRepository.findByApplicationId(applicationId); + for (ApplicationFormEntity applicationForm:applicationFormEntity){ + FormEntity formEntity=applicationForm.getForm(); + List contentList = Utils.convertJsonStringToList(formEntity.getContent(), ContentResponseBean.class); + List applicationFormFieldEntityList=applicationFormFieldRepository.findByApplicationFormId(applicationForm.getId()); + for (ApplicationFormFieldEntity applicationFormFieldEntity:applicationFormFieldEntityList) { + contentList.forEach(contentResponseBean -> { + if (("fileupload".equals(contentResponseBean.getName()) || GepafinConstant.FILE_SELECT.equals(contentResponseBean.getName())) + && contentResponseBean.getId().equals(applicationFormFieldEntity.getFieldId())) { + String updatedValue = removeDocumentIdFromFieldValue(applicationFormFieldEntity.getFieldValue(), documentId); + applicationFormFieldEntity.setFieldValue(updatedValue); + applicationFormFieldRepository.save(applicationFormFieldEntity); + } + }); + } + } + callId = applicationEntity.getCall().getId(); log.info("Processing document of type APPLICATION. Resolved applicationId={}, callId={}", applicationId, callId); } else if(DocumentSourceTypeEnum.AMENDMENT.getValue().equalsIgnoreCase(documentEntity.getSource())){ amendmentId = documentEntity.getSourceId(); ApplicationEntity applicationEntity = applicationAmendmentRequestRepository.findApplicationByAmendmentId(amendmentId); + Optional applicationAmendmentRequestEntity=applicationAmendmentRequestRepository.findByIdAndIsDeletedFalse(amendmentId); + Map amendmentFormFieldMap = Utils + .convertJsonStringToList(applicationAmendmentRequestEntity.get().getFormFields(), AmendmentFormField.class) + .stream().collect(Collectors.toMap(AmendmentFormField::getFieldId, Function.identity())); + for (Map.Entry entry : amendmentFormFieldMap.entrySet()) { + AmendmentFormField amendmentFormField=entry.getValue(); + String updatedValue = removeDocumentIdFromFieldValue(amendmentFormField.getFieldValue(), documentId); + amendmentFormField.setFieldValue(updatedValue); + } + String amendmentDocs=applicationAmendmentRequestEntity.get().getAmendmentDocument(); + Map amendmentDocument=Utils.convertIntoJson(amendmentDocs); + String amendmentDocuments= (String) amendmentDocument.get("amendmentDocuments"); + if(amendmentDocuments!=null){ + String updatedValue = removeDocumentIdFromFieldValue(amendmentDocuments, documentId); + amendmentDocument.put("amendmentDocuments", updatedValue); + + // Step 4: Convert map back to JSON string + String updatedAmendmentDocs = Utils.convertMapIntoJsonString(amendmentDocument); // implement this if not available + + // Step 5: Set it back to entity + applicationAmendmentRequestEntity.get().setAmendmentDocument(updatedAmendmentDocs); + } + applicationAmendmentRequestEntity.get().setFormFields(Utils.convertListToJsonString(amendmentFormFieldMap.values().stream().toList())); + applicationAmendmentRequestRepository.save(applicationAmendmentRequestEntity.get()); + applicationId = applicationEntity.getId(); callId = applicationEntity.getCall().getId(); log.info("Processing document of type AMENDMENT. Resolved amendmentId={}, applicationId={}, callId={}", amendmentId, applicationId, callId); } else if(DocumentSourceTypeEnum.EVALUATION.getValue().equalsIgnoreCase(documentEntity.getSource())){ evaluationId = documentEntity.getSourceId(); ApplicationEntity applicationEntity = applicationEvaluationRepository.findApplicationByEvaluationId(evaluationId); + ApplicationEvaluationEntity entity=applicationEvaluationRepository.findByApplicationId(applicationEntity.getId()); + List allDocs = applicationEvaluationDao.prepareEvaluationDocumentBeanList(entity); + List updatedDocs=allDocs; + allDocs = allDocs.stream() + .filter(doc -> doc.getFileValue().equals(removeDocumentIdFromFieldValue(doc.getFileValue(), documentId))) + .collect(Collectors.toList()); + + + String updatedEvaluationDocJson = Utils.convertObjectToJson(allDocs); + entity.setEvaluationDocument(updatedEvaluationDocJson); + applicationEvaluationRepository.save(entity); applicationId = applicationEntity.getId(); callId = applicationEntity.getCall().getId(); log.info("Processing document of type EVALUATION. Resolved evaluationId={}, applicationId={}, callId={}", evaluationId, applicationId, callId); @@ -343,4 +408,19 @@ public class DocumentDao { throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.ERROR_MOVING_FILE_TO_DELETED_FOLDER)); } } + + public String removeDocumentIdFromFieldValue(String fieldValue, Long documentId) { + if (fieldValue == null || fieldValue.isBlank()) { + return fieldValue; + } + + List documentIdList = new ArrayList<>(Arrays.asList(fieldValue.split(","))); + documentIdList.replaceAll(String::trim); // Trim spaces for safety + + boolean removed = documentIdList.removeIf(id -> id.equals(String.valueOf(documentId))); + + // Return updated value only if modified, else return original + return removed ? String.join(",", documentIdList) : fieldValue; + } + } From 54b45733801cef6ab7ccfd1914b09a3b7727b30e Mon Sep 17 00:00:00 2001 From: rajesh Date: Wed, 23 Jul 2025 15:48:40 +0530 Subject: [PATCH 12/75] Done ticket GEPAFINBE-235 --- .../entities/ApplicationFormView.java | 5 + .../db/changelog/db.changelog-1.0.0.xml | 4 + ...pdate_application_form_view_23_07_2025.sql | 108 ++++++++++++++++++ 3 files changed, 117 insertions(+) create mode 100644 src/main/resources/db/dump/update_application_form_view_23_07_2025.sql diff --git a/src/main/java/net/gepafin/tendermanagement/entities/ApplicationFormView.java b/src/main/java/net/gepafin/tendermanagement/entities/ApplicationFormView.java index 0af565bf..e99d43ca 100644 --- a/src/main/java/net/gepafin/tendermanagement/entities/ApplicationFormView.java +++ b/src/main/java/net/gepafin/tendermanagement/entities/ApplicationFormView.java @@ -118,4 +118,9 @@ public class ApplicationFormView { @Column(name = "INSTRUCTOR_NAME") private String instructorName; + @Column(name = "SUBMISSION_DATE") + private LocalDate submissionDate; + + @Column(name = "SUBMISSION_TIME") + private LocalTime submissionTime; } 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 ef0f3447..c7f4e41e 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 @@ -3004,4 +3004,8 @@ + + + + diff --git a/src/main/resources/db/dump/update_application_form_view_23_07_2025.sql b/src/main/resources/db/dump/update_application_form_view_23_07_2025.sql new file mode 100644 index 00000000..eec055ec --- /dev/null +++ b/src/main/resources/db/dump/update_application_form_view_23_07_2025.sql @@ -0,0 +1,108 @@ + +DROP VIEW IF EXISTS gepafin_schema.application_form_view ; + +CREATE OR REPLACE VIEW gepafin_schema.application_form_view AS +SELECT app_data.id, + app_data.call_id, + app_data.application_form_id, + app_data.form_id, + app_data.application_id, + field_data.value ->> 'id'::text AS field_id, + COALESCE(( SELECT s.value ->> 'value'::text + FROM jsonb_array_elements(field_data.value -> 'settings'::text) s(value) + WHERE (s.value ->> 'name'::text) = 'label'::text + LIMIT 1), field_data.value ->> 'label'::text) AS field_label, + ( SELECT (s.value ->> 'value'::text)::boolean AS bool + FROM jsonb_array_elements(field_data.value -> 'settings'::text) s(value) + WHERE (s.value ->> 'name'::text) = 'reportEnable'::text + LIMIT 1) AS report_enable, + COALESCE(( SELECT s.value ->> 'value'::text + FROM jsonb_array_elements(field_data.value -> 'settings'::text) s(value) + WHERE (s.value ->> 'name'::text) = 'reportHeader'::text + LIMIT 1), field_data.value ->> 'reportHeader'::text) AS report_header, + field_data.value ->> 'name'::text AS field_type, + CASE + WHEN (field_data.value ->> 'name'::text) = 'fileupload'::text THEN to_jsonb(( SELECT string_agg(d.file_name::text, ', '::text) AS string_agg + FROM unnest(string_to_array(app_data.field_value, ','::text)) file_ids(file_id) + JOIN gepafin_schema.document d ON d.id::text = file_ids.file_id + WHERE d.is_deleted = false)) + WHEN (field_data.value ->> 'name'::text) = ANY (ARRAY['checkboxes'::text, 'select'::text, 'radio'::text]) THEN + CASE + WHEN app_data.field_value ~~ '[%'::text THEN to_jsonb(( SELECT string_agg(opt.value ->> 'label'::text, ', '::text) AS string_agg + FROM jsonb_array_elements_text(app_data.field_value::jsonb) selected_id(value) + CROSS JOIN LATERAL ( SELECT s.value + FROM jsonb_array_elements(field_data.value -> 'settings'::text) s(value) + WHERE (s.value ->> 'name'::text) = 'options'::text) options_setting, + LATERAL jsonb_array_elements(options_setting.value -> 'value'::text) opt(value) + WHERE (opt.value ->> 'name'::text) = selected_id.value)) + ELSE to_jsonb(( SELECT opt.value ->> 'label'::text + FROM ( SELECT s.value + FROM jsonb_array_elements(field_data.value -> 'settings'::text) s(value) + WHERE (s.value ->> 'name'::text) = 'options'::text) options_setting, + LATERAL jsonb_array_elements(options_setting.value -> 'value'::text) opt(value) + WHERE (opt.value ->> 'name'::text) = app_data.field_value + LIMIT 1)) + END + ELSE to_jsonb(app_data.field_value) + END AS field_value, + app_data.status, + app_data.amount_requested, + app_data.amount_accepted, + app_data.is_deleted, + app_data.hub_id, + app_data.user_id, + app_data.evaluation_version, + app_data.company_id, + c.company_name, + c.vat_number AS company_vat_number, + c.codice_ateco, + c.codice_fiscale AS company_codice_fiscale, + p.protocol_number, + DATE(app_data.submission_date) AS submission_date, + TO_CHAR(app_data.submission_date, 'HH24:MI:SS') AS submission_time, + b.codice_fiscale AS user_codice_fiscale, + COALESCE(NULLIF(TRIM(BOTH FROM concat(COALESCE(u.first_name, ''::character varying), ' ', COALESCE(u.last_name, ''::character varying))), ''::text), ''::text) AS user_name, + COALESCE( NULLIF(TRIM(BOTH FROM CONCAT(COALESCE(aauser.first_name, ''), ' ', COALESCE(aauser.last_name, ''))),''),'NA') AS instructor_name, + uwc.is_legal_representant AS legal_representative, + cl.name AS call_title, + cl.end_date AS call_end_date, + cl.end_time AS call_end_time, + cl.start_date AS call_start_date, + cl.start_time AS call_start_time + FROM ( SELECT a.id AS application_id, + a.call_id, + a.protocol_number, + af.id AS application_form_id, + af.form_id, + aff.id, + aff.field_value, + a.status, + a.amount_requested, + a.amount_accepted, + a.is_deleted, + a.hub_id, + a.user_id, + a.evaluation_version, + a.created_date, + a.company_id, + a.submission_date, + aff.field_id, + f.content + FROM gepafin_schema.application a + JOIN gepafin_schema.application_form af ON af.application_id = a.id + JOIN gepafin_schema.application_form_field aff ON aff.application_form_id = af.id + JOIN gepafin_schema.form f ON f.id = af.form_id + WHERE a.is_deleted = false) app_data + CROSS JOIN LATERAL ( SELECT jsonb_array_elements.value + FROM jsonb_array_elements(app_data.content::jsonb) jsonb_array_elements(value) + WHERE (jsonb_array_elements.value ->> 'id'::text) = app_data.field_id::text) field_data(value) + LEFT JOIN gepafin_schema.call cl ON app_data.call_id = cl.id + LEFT JOIN gepafin_schema.company c ON app_data.company_id = c.id + LEFT JOIN gepafin_schema.protocol p ON app_data.protocol_number = p.id + LEFT JOIN gepafin_schema.gepafin_user u ON app_data.user_id = u.id + LEFT JOIN gepafin_schema.user_with_company uwc ON app_data.user_id = uwc.user_id AND app_data.company_id = uwc.company_id AND uwc.is_deleted = false + LEFT JOIN gepafin_schema.beneficiary b ON u.beneficiary_id = b.id + LEFT JOIN gepafin_schema.assigned_applications aa ON app_data.application_id = aa.application_id + LEFT JOIN gepafin_schema.gepafin_user aauser ON aa.user_id = aauser.id + WHERE app_data.id IS NOT NULL AND (app_data.status::text <> ALL (ARRAY['DRAFT'::character varying::text, 'AWAITING'::character varying::text, 'READY'::character varying::text])) + ORDER BY app_data.id, (field_data.value ->> 'id'::text); \ No newline at end of file From 39d3d7dce5d41fb0ec4666dfed89fc67ae0427c1 Mon Sep 17 00:00:00 2001 From: rajesh Date: Thu, 24 Jul 2025 12:22:59 +0530 Subject: [PATCH 13/75] Code for ticket GEPAFINBE-226 --- .../dao/ApplicationAmendmentRequestDao.java | 157 ++++++++++++------ .../ApplicationAmendmentRequestEntity.java | 7 + .../db/changelog/db.changelog-1.0.0.xml | 7 + 3 files changed, 124 insertions(+), 47 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java index 0cded205..21b4b716 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java @@ -1151,6 +1151,8 @@ public class ApplicationAmendmentRequestDao { ApplicationAmendmentRequestEntity oldApplicationAmendmentEntity = Utils.getClonedEntityForData(applicationAmendmentRequestEntity); Long currentResponseDays = applicationAmendmentRequestEntity.getResponseDays() != null ? applicationAmendmentRequestEntity.getResponseDays() : 0L; applicationAmendmentRequestEntity.setResponseDays(currentResponseDays + newResponseDays); + applicationAmendmentRequestEntity.setExtendedDays(newResponseDays); + applicationAmendmentRequestEntity.setExtensionDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); applicationAmendmentRequestEntity.setEndDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now().plusDays(newResponseDays))); applicationAmendmentRequestEntity.setStatus(ApplicationAmendmentRequestEnum.AWAITING.getValue()); applicationAmendmentRequestEntity.getApplicationEvaluationEntity().setStatus(ApplicationEvaluationStatusTypeEnum.SOCCORSO.getValue()); @@ -1639,53 +1641,53 @@ public class ApplicationAmendmentRequestDao { return updated; } - public long calculateSuspendedDays(List amendments) { - List> periods = amendments.stream() - .filter(amendmentRequest -> amendmentRequest.getStartDate() != null) - .map(amendmentRequest -> { - LocalDateTime start = amendmentRequest.getStartDate(); - LocalDateTime end; - - String status = amendmentRequest.getStatus(); - if (Boolean.TRUE.equals(ApplicationAmendmentRequestEnum.CLOSE.getValue().equals(status)) && amendmentRequest.getClosingDate() != null) { - end = amendmentRequest.getClosingDate(); - } else if (Boolean.TRUE.equals(ApplicationAmendmentRequestEnum.EXPIRED.getValue().equals(status)) && amendmentRequest.getEndDate() != null) { - end = amendmentRequest.getStartDate().plusDays(amendmentRequest.getResponseDays()); - }else { - end= amendmentRequest.getEndDate(); - } - - return Pair.of(start, end); - }) - .filter(Objects::nonNull) - .sorted(Comparator.comparing(Pair::getLeft)) - .collect(Collectors.toList()); - - long totalDays = 0; - LocalDateTime currentStart = null; - LocalDateTime currentEnd = null; - - for (Pair period : periods) { - if (currentStart == null) { - currentStart = period.getLeft(); - currentEnd = period.getRight(); - } else if (!period.getLeft().isAfter(currentEnd)) { - // Merge overlapping/touching periods - currentEnd = currentEnd.isAfter(period.getRight()) ? currentEnd : period.getRight(); - } else { - // Non-overlapping: count previous period - totalDays += ChronoUnit.DAYS.between(currentStart.toLocalDate(), currentEnd.toLocalDate()); - currentStart = period.getLeft(); - currentEnd = period.getRight(); - } - } - - if (currentStart != null && currentEnd != null) { - totalDays += ChronoUnit.DAYS.between(currentStart.toLocalDate(), currentEnd.toLocalDate()); - } - - return totalDays; - } +// public long calculateSuspendedDays(List amendments) { +// List> periods = amendments.stream() +// .filter(amendmentRequest -> amendmentRequest.getStartDate() != null) +// .map(amendmentRequest -> { +// LocalDateTime start = amendmentRequest.getStartDate(); +// LocalDateTime end; +// +// String status = amendmentRequest.getStatus(); +// if (Boolean.TRUE.equals(ApplicationAmendmentRequestEnum.CLOSE.getValue().equals(status)) && amendmentRequest.getClosingDate() != null) { +// end = amendmentRequest.getClosingDate(); +// } else if (Boolean.TRUE.equals(ApplicationAmendmentRequestEnum.EXPIRED.getValue().equals(status)) && amendmentRequest.getEndDate() != null) { +// end = amendmentRequest.getStartDate().plusDays(amendmentRequest.getResponseDays()); +// }else { +// end= amendmentRequest.getEndDate(); +// } +// +// return Pair.of(start, end); +// }) +// .filter(Objects::nonNull) +// .sorted(Comparator.comparing(Pair::getLeft)) +// .collect(Collectors.toList()); +// +// long totalDays = 0; +// LocalDateTime currentStart = null; +// LocalDateTime currentEnd = null; +// +// for (Pair period : periods) { +// if (currentStart == null) { +// currentStart = period.getLeft(); +// currentEnd = period.getRight(); +// } else if (!period.getLeft().isAfter(currentEnd)) { +// // Merge overlapping/touching periods +// currentEnd = currentEnd.isAfter(period.getRight()) ? currentEnd : period.getRight(); +// } else { +// // Non-overlapping: count previous period +// totalDays += ChronoUnit.DAYS.between(currentStart.toLocalDate(), currentEnd.toLocalDate()); +// currentStart = period.getLeft(); +// currentEnd = period.getRight(); +// } +// } +// +// if (currentStart != null && currentEnd != null) { +// totalDays += ChronoUnit.DAYS.between(currentStart.toLocalDate(), currentEnd.toLocalDate()); +// } +// +// return totalDays; +// } @@ -1711,4 +1713,65 @@ public class ApplicationAmendmentRequestDao { } return applicationAmendmentRequestEntity; } + public long calculateSuspendedDays(List amendments) { + List> periods = amendments.stream() + .filter(amendmentRequest -> amendmentRequest.getStartDate() != null) + .flatMap(amendmentRequest -> { + List> result = new ArrayList<>(); + + LocalDateTime start = amendmentRequest.getStartDate(); + String status = amendmentRequest.getStatus(); + Long responseDays = amendmentRequest.getResponseDays() != null ? amendmentRequest.getResponseDays() : 0L; + LocalDateTime extensionDate = amendmentRequest.getExtensionDate(); + Long extendedDays = amendmentRequest.getExtendedDays() != null ? amendmentRequest.getExtendedDays() : 0L; + + if (ApplicationAmendmentRequestEnum.CLOSE.getValue().equals(status) && amendmentRequest.getClosingDate() != null) { + if (extensionDate != null && amendmentRequest.getClosingDate().isAfter(extensionDate)) { + long overlappingExtensionDays = ChronoUnit.DAYS.between(extensionDate.toLocalDate(), amendmentRequest.getClosingDate().toLocalDate()); + long adjustedInitialPeriod = responseDays - overlappingExtensionDays; + + result.add(Pair.of(start, start.plusDays(adjustedInitialPeriod))); + } else { + result.add(Pair.of(start, amendmentRequest.getClosingDate())); + } + } else if (ApplicationAmendmentRequestEnum.EXPIRED.getValue().equals(status)) { + result.add(Pair.of(start, start.plusDays(responseDays))); + } else { + if (amendmentRequest.getEndDate() != null) { + result.add(Pair.of(start, amendmentRequest.getEndDate())); + } else { + result.add(Pair.of(start, start.plusDays(responseDays))); + } + } + + return result.stream(); + }) + .filter(Objects::nonNull) + .sorted(Comparator.comparing(Pair::getLeft)) + .collect(Collectors.toList()); + + long totalDays = 0; + LocalDateTime currentStart = null; + LocalDateTime currentEnd = null; + + for (Pair period : periods) { + if (currentStart == null) { + currentStart = period.getLeft(); + currentEnd = period.getRight(); + } else if (!period.getLeft().isAfter(currentEnd)) { + currentEnd = currentEnd.isAfter(period.getRight()) ? currentEnd : period.getRight(); + } else { + totalDays += ChronoUnit.DAYS.between(currentStart.toLocalDate(), currentEnd.toLocalDate()); + currentStart = period.getLeft(); + currentEnd = period.getRight(); + } + } + + if (currentStart != null && currentEnd != null) { + totalDays += ChronoUnit.DAYS.between(currentStart.toLocalDate(), currentEnd.toLocalDate()); + } + + return totalDays; + } + } diff --git a/src/main/java/net/gepafin/tendermanagement/entities/ApplicationAmendmentRequestEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/ApplicationAmendmentRequestEntity.java index eb71f5c1..0d917599 100644 --- a/src/main/java/net/gepafin/tendermanagement/entities/ApplicationAmendmentRequestEntity.java +++ b/src/main/java/net/gepafin/tendermanagement/entities/ApplicationAmendmentRequestEntity.java @@ -62,4 +62,11 @@ public class ApplicationAmendmentRequestEntity extends BaseEntity { @Convert(converter = EmailSendResponseConverter.class) @Column(name = "EMAIL_SEND_RESPONSE", columnDefinition = "TEXT") private List emailSendResponse; + + @Column(name = "EXTENDED_DAYS") + private Long extendedDays; + + @Column(name = "EXTENSION_DATE") + private LocalDateTime extensionDate; + } 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 a911a3ac..c5bc6193 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 @@ -2829,4 +2829,11 @@ + + + + + + + From 481e3bd97ff3db1908b80586067a268446cf15d2 Mon Sep 17 00:00:00 2001 From: rajesh Date: Fri, 25 Jul 2025 14:43:19 +0530 Subject: [PATCH 14/75] Removed extra spacing between fields in pdf --- .../java/net/gepafin/tendermanagement/dao/PdfDao.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java b/src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java index 9eda7968..6dc54807 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java @@ -137,6 +137,7 @@ public class PdfDao { Map stateFieldMap= new HashMap<>(); Paragraph labelParagraph = new Paragraph(label, labelFont); + labelParagraph.setSpacingAfter(-10f); document.add(labelParagraph); float leftMargin = 20f; PdfContentByte canvas = writer.getDirectContent(); @@ -202,7 +203,9 @@ public class PdfDao { valueCell.setPaddingLeft(leftMargin); // Increase left margin for value valueCell.setBorder(Rectangle.NO_BORDER); // Remove border for value cell valueCell.setVerticalAlignment(Element.ALIGN_MIDDLE); - valueCell.setHorizontalAlignment(Element.ALIGN_LEFT); valueCell.setCellEvent(new RoundedCorners()); // Apply rounded corners + valueCell.setHorizontalAlignment(Element.ALIGN_LEFT); + valueCell.setCellEvent(new RoundedCorners()); // Apply rounded corners + valueTable.setSpacingAfter(-15f); // Add the cell to the table valueTable.addCell(valueCell); @@ -285,6 +288,7 @@ public class PdfDao { valueCell.setHorizontalAlignment(Element.ALIGN_LEFT); valueCell.setCellEvent(new RoundedCorners()); // Apply rounded corners valueTable.addCell(valueCell); + valueTable.setSpacingAfter(-15f); document.add(valueTable); } } @@ -541,6 +545,8 @@ public class PdfDao { labelCell.setBorder(Rectangle.NO_BORDER); labelCell.setGrayFill(7); labelCell.setPadding(5); + labelParagraph.setSpacingAfter(-10f); + // Create a PdfPTable with 1 column and add the PdfPCell to it PdfPTable table = new PdfPTable(1); From 7b5ef30c7d16a790d2f61e4eed963b31fdc66e25 Mon Sep 17 00:00:00 2001 From: rajesh Date: Tue, 29 Jul 2025 17:33:17 +0530 Subject: [PATCH 15/75] Fixed formula calculation issue in application --- .../tendermanagement/dao/ApplicationDao.java | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java index 198a4ede..a0ae0651 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java @@ -1786,12 +1786,15 @@ public class ApplicationDao { String expression = formula; for (String variable : variables) { Double value = variableValues.get(variable); - if (value != null) { - // Replace {variable} with its corresponding value in the formula - expression = expression.replace("{" + variable + "}", String.valueOf(value)); - } - } + String placeholder = "{" + variable + "}"; + // If value is null, use 0 instead + String replacement = String.valueOf(value != null ? value : 0); + expression = expression.replace(placeholder, replacement); + } + if (expression.matches(".*\\{.*\\}.*")) { + return 0; + } // Step 4: Evaluate the mathematical expression return Utils.evaluateExpression(expression); } From 517a8da925a55aded78f0e0bdf4a40a458ec7e76 Mon Sep 17 00:00:00 2001 From: rajesh Date: Tue, 29 Jul 2025 17:44:07 +0530 Subject: [PATCH 16/75] Fixed issue of formula calculation in application --- .../gepafin/tendermanagement/dao/ApplicationDao.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java index 21522588..9875f4ac 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java @@ -1792,10 +1792,14 @@ public class ApplicationDao { String expression = formula; for (String variable : variables) { Double value = variableValues.get(variable); - if (value != null) { - // Replace {variable} with its corresponding value in the formula - expression = expression.replace("{" + variable + "}", String.valueOf(value)); - } + String placeholder = "{" + variable + "}"; + + // If value is null, use 0 instead + String replacement = String.valueOf(value != null ? value : 0); + expression = expression.replace(placeholder, replacement); + } + if (expression.matches(".*\\{.*\\}.*")) { + return 0; } // Step 4: Evaluate the mathematical expression From 16c190d3172d0616e006896bd9590d044ba84636 Mon Sep 17 00:00:00 2001 From: rajesh Date: Tue, 29 Jul 2025 21:10:37 +0530 Subject: [PATCH 17/75] Removed validation for calculation formula --- .../java/net/gepafin/tendermanagement/dao/ApplicationDao.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java index 9875f4ac..b78a2905 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java @@ -645,7 +645,6 @@ public class ApplicationDao { } } } - calculationProcessForFormula(applicationFormEntity,contentResponseBeans,applicationFormFieldRequestBean,fieldValidator); Utils.setIfUpdated(applicationFormFieldEntity::getFieldId, applicationFormFieldEntity::setFieldId, applicationFormFieldRequestBean.getFieldId()); if (applicationFormFieldRequestBean.getFieldValue() != null) { From 91e1324bb0ce789c5c38b29bcb983c9493da1977 Mon Sep 17 00:00:00 2001 From: rajesh Date: Wed, 30 Jul 2025 11:40:09 +0530 Subject: [PATCH 18/75] Commented external protocol api --- .../net/gepafin/tendermanagement/dao/ApplicationDao.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java index b78a2905..10a36fbd 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java @@ -1064,9 +1064,9 @@ public class ApplicationDao { ProtocolEntity protocolEntity = protocolDao.createProtocolEntity(applicationEntity, protocolNumber, userEntity.getHub().getId(),true); protocolDao.saveProtocolEntity(protocolEntity); applicationEntity.setProtocol(protocolEntity); - if(Boolean.TRUE.equals(hub.getUniqueUuid().equals(sviluppumbriaUuid))) { - protocolEntity = protocolDao.createExternalProtocol(applicationEntity, company, protocolEntity); - } +// if(Boolean.TRUE.equals(hub.getUniqueUuid().equals(sviluppumbriaUuid))) { +// protocolEntity = protocolDao.createExternalProtocol(applicationEntity, company, protocolEntity); +// } applicationEntity.setStatus(ApplicationStatusTypeEnum.SUBMIT.getValue()); applicationEntity.setSubmissionDate(protocolEntity.getCreatedDate()); applicationEntity = applicationRepository.save(applicationEntity); From 2521eb9cc88ca214ab033a7f4b9d56b9212f09af Mon Sep 17 00:00:00 2001 From: rajesh Date: Wed, 30 Jul 2025 13:35:03 +0530 Subject: [PATCH 19/75] Updated year field in pdf --- .../net/gepafin/tendermanagement/dao/ApplicationDao.java | 6 +++--- .../java/net/gepafin/tendermanagement/dao/FormDao.java | 5 +++++ .../java/net/gepafin/tendermanagement/dao/PdfDao.java | 8 +++++--- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java index 10a36fbd..f9570895 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java @@ -1670,12 +1670,12 @@ public class ApplicationDao { // } } - public void calculationProcessForFormula(ApplicationFormEntity applicationFormEntity, List contentResponseBeans, ApplicationFormFieldRequestBean applicationFormFieldRequestBean,FieldValidator fieldValidator) { + public void calculationProcessForFormula(ApplicationFormEntity applicationFormEntity, List contentResponseBeans,String fromFieldId,String formFieldValue,FieldValidator fieldValidator) { List formulaValue = new ArrayList<>(); String formulaValueOpt=null; String label=null; for (ContentResponseBean contentResponseBean:contentResponseBeans){ - if(contentResponseBean.getId().equals(applicationFormFieldRequestBean.getFieldId())){ + if(contentResponseBean.getId().equals(fromFieldId)){ for (SettingResponseBean settingResponseBean:contentResponseBean.getSettings()){ if (settingResponseBean.getName().equals("label")){ label= String.valueOf(settingResponseBean.getValue()); @@ -1689,7 +1689,7 @@ public class ApplicationDao { } } Map mappedFormulaValue = new HashMap<>(); - Object fieldValue = applicationFormFieldRequestBean.getFieldValue(); + Object fieldValue = formFieldValue; if (formulaValueOpt != null && fieldValue==null) { fieldValue=0; } diff --git a/src/main/java/net/gepafin/tendermanagement/dao/FormDao.java b/src/main/java/net/gepafin/tendermanagement/dao/FormDao.java index 47859a3b..8ce395d0 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/FormDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/FormDao.java @@ -76,6 +76,9 @@ public class FormDao { @Autowired private HttpServletRequest request; + @Autowired + private ApplicationDao applicationDao; + public FormEntity saveFormEntity(FormEntity formEntity){ formEntity=formRepository.save(formEntity); return formEntity; @@ -419,6 +422,8 @@ public class FormDao { .maxLength(value, fieldValidatorBean.getMaxLength(), fieldLabel,fieldValidatorBean.getMax(),contentResponseBean) // Only applies if maxLength is not null .matchesPattern(value, fieldValidatorBean.getPattern(), fieldLabel) // Only applies if pattern is present .validateCustom(value, fieldValidatorBean.getCustom(), fieldLabel,contentResponseBean); // Add the custom validation here + +// applicationDao.calculationProcessForFormula(applicationFormEntity,formResponseBean.getContent(),fieldId,value,validator); if (fieldValidatorBean.getCustom() != null && fieldValidatorBean.getCustom().equals(GepafinConstant.IS_PIVA)) { Long hubId = applicationEntity.getHubId(); String error = validateVatNumber(value, fieldLabel,hubId); diff --git a/src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java b/src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java index 6dc54807..afde01ab 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java @@ -392,10 +392,12 @@ public class PdfDao { if (Boolean.TRUE.equals(formulaEnabledMap.get(key)) && Boolean.TRUE.equals(GepafinConstant.NUMERIC.equalsIgnoreCase(fieldTypeMap.get(key)))) { calculateValue(key, fieldValue, formulaTypeMap, columnSums); } - if(Boolean.TRUE.equals(Utils.isNumeric(fieldValue))){ - fieldValue=Utils.convertToItalianFormat(fieldValue); + String fieldLabel = stateFieldMap.getOrDefault(key, ""); + if(Boolean.FALSE.equals(fieldLabel.equalsIgnoreCase("Anno"))) { + if (Boolean.TRUE.equals(Utils.isNumeric(fieldValue))) { + fieldValue = Utils.convertToItalianFormat(fieldValue); + } } - PdfPCell dataCell = PdfUtils.htmlToPdfPCell(fieldValue != null ? fieldValue : "", textFont); dataCell.setBackgroundColor(new BaseColor(239, 243, 248)); // Light blue for the cell dataCell.setMinimumHeight(30f); From 26701bae8b3aa1a225870c17a9219dfffda757b0 Mon Sep 17 00:00:00 2001 From: rajesh Date: Fri, 1 Aug 2025 13:20:24 +0530 Subject: [PATCH 20/75] Fixed ndg sequence issue --- .../constants/GepafinConstant.java | 1 + .../tendermanagement/dao/AppointmentDao.java | 52 ++++++++++++++++--- .../db/changelog/db.changelog-1.0.0.xml | 7 +++ 3 files changed, 52 insertions(+), 8 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java b/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java index 3874fc83..1aaf53ec 100644 --- a/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java +++ b/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java @@ -574,6 +574,7 @@ public class GepafinConstant { public static final String CREATE_NDG="CHECK_OR_CREATE_NDG_CODE"; public static final String NDG_NOT_FOUND="ndg.not.found"; public static final String EMAIL_PEC_REQUIRED="email.pec.cannot.null"; + public static final String COMPANY_NAME_JSON="denominazione"; } diff --git a/src/main/java/net/gepafin/tendermanagement/dao/AppointmentDao.java b/src/main/java/net/gepafin/tendermanagement/dao/AppointmentDao.java index 76a7fcff..9889993e 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/AppointmentDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/AppointmentDao.java @@ -540,10 +540,10 @@ public class AppointmentDao { // Try retrieving NDG by VAT number NdganagEntity ndganagEntity = ndganagRepository.findByVatNumber(company.getVatNumber()); AppointmentLoginResponse ndgResponse=new AppointmentLoginResponse(); - if (ndganagEntity != null || ndganagEntity.getNdg() != null) { + if (ndganagEntity != null && ndganagEntity.getNdg() != null) { ndgResponse.setNdg(ndganagEntity.getNdg()); }else { - ndgResponse = retrieveNdgByVatNumber(company.getVatNumber(), authorizationToken, hub, application); + ndgResponse = retrieveNdgByVatNumber(company.getVatNumber(), authorizationToken, hub, application,company); } if (isNdgValid(ndgResponse.getNdg())) { saveNdg(application, company, ndgResponse.getNdg()); @@ -720,20 +720,38 @@ public class AppointmentDao { } } - private AppointmentLoginResponse retrieveNdgByVatNumber(String vatNumber, String authorizationToken, HubEntity hub, ApplicationEntity application) { + private AppointmentLoginResponse retrieveNdgByVatNumber(String vatNumber, String authorizationToken, HubEntity hub, ApplicationEntity application,CompanyEntity company) { try { log.info("Initiating NDG retrieval by VAT number | ApplicationId: {}, HubId: {}, VAT: {}", application.getId(), hub.getId(), vatNumber); // Prepare the NDG request String responseJson = getNdgFromExternalService(vatNumber, authorizationToken); // Parse and return the NDG response - return parseNdgResponse(responseJson); + AppointmentLoginResponse loginResponse=parseNdgResponse(responseJson); + ObjectMapper objectMapper = new ObjectMapper(); + JsonNode rootNode = null; + try { + rootNode = objectMapper.readTree(responseJson); + } catch (JsonProcessingException e) { + throw new RuntimeException(e); + } + JsonNode dataArray = rootNode.get(GepafinConstant.DATA_STRING); + JsonNode firstDataEntry = dataArray.get(0); + NdganagEntity ndganagEntity=new NdganagEntity(); + ndganagEntity.setNdg(loginResponse.getNdg()); + ndganagEntity.setVatNumber(loginResponse.getVatNumber()); + ndganagEntity.setCodiceFiscale(loginResponse.getCodecFiscale()); + ndganagEntity.setJson(firstDataEntry.toString()); + ndganagEntity.setIsDeleted(Boolean.FALSE); + ndganagEntity.setCompanyName(company.getCompanyName()); + ndganagRepository.save(ndganagEntity); + return loginResponse; } catch (FeignException.Forbidden forbiddenException) { log.error("403 Forbidden during NDG retrieval | ApplicationId: {}, HubId: {}", application.getId(), hub.getId()); logForbiddenError(); // Regenerate the token and retry String newAuthorizationToken = regenerateTokenAndSave(hub, application); - return retrieveNdgByVatNumber(vatNumber, newAuthorizationToken, hub, application); + return retrieveNdgByVatNumber(vatNumber, newAuthorizationToken, hub, application,company); } catch (Exception e) { log.error("Error during NDG retrieval | ApplicationId: {}, HubId: {}, Message: {}", application.getId(), hub.getId(), e.getMessage(), e); throw new RuntimeException("NDG retrieval failed.", e); @@ -883,6 +901,7 @@ public class AppointmentDao { public AppointmentLoginResponse parseNdgResponse(String jsonResponse) { AppointmentLoginResponse loginResponse = new AppointmentLoginResponse(); String ndg=extractNdg(jsonResponse); + if (ndg==null){ return null;} else { loginResponse.setNdg(ndg); @@ -1441,7 +1460,7 @@ public class AppointmentDao { log.info("Initiating NDG retrieval by VAT number | HubId: {}, VAT: {}", hub.getId(), vatNumber); // Prepare the NDG request jsonResponse=getNdgFromExternalService(vatNumber, authorizationToken); - checkAndSaveNdg(jsonResponse, ndgResponse); + checkAndSaveNdg(jsonResponse, ndgResponse,vatNumber); // Parse and return the NDG response } catch (FeignException.Forbidden forbiddenException) { log.error("403 Forbidden during NDG retrieval | HubId: {}", hub.getId()); @@ -1449,7 +1468,7 @@ public class AppointmentDao { // Regenerate the token and retry String newAuthorizationToken = regenerateTokenAndSave(hub, null); jsonResponse= getNdgFromExternalService(vatNumber,newAuthorizationToken); - if (checkAndSaveNdg(jsonResponse, ndgResponse)) return null; + if (checkAndSaveNdg(jsonResponse, ndgResponse,vatNumber)) return null; } catch (Exception e) { log.error("Error during NDG retrieval |, HubId: {}, Message: {}", hub.getId(), e.getMessage(), e); throw new RuntimeException("NDG retrieval failed.", e); @@ -1460,8 +1479,25 @@ public class AppointmentDao { return ndgResponse; } - private boolean checkAndSaveNdg(String jsonResponse, NdgResponse ndgResponse) { + private boolean checkAndSaveNdg(String jsonResponse, NdgResponse ndgResponse,String vatNumber) { String ndg=extractNdg(jsonResponse); + ObjectMapper objectMapper = new ObjectMapper(); + JsonNode rootNode = null; + try { + rootNode = objectMapper.readTree(jsonResponse); + } catch (JsonProcessingException e) { + throw new RuntimeException(e); + } + JsonNode dataArray = rootNode.get(GepafinConstant.DATA_STRING); + JsonNode firstDataEntry = dataArray.get(0); + String comapnyName=normalizeNullValue(firstDataEntry.get(GepafinConstant.COMPANY_NAME_JSON).asText()); + NdganagEntity ndganagEntity=new NdganagEntity(); + ndganagEntity.setNdg(ndg); + ndganagEntity.setVatNumber(vatNumber); + ndganagEntity.setJson(firstDataEntry.toString()); + ndganagEntity.setIsDeleted(Boolean.FALSE); + ndganagEntity.setCompanyName(comapnyName); + ndganagRepository.save(ndganagEntity); if (ndg==null){ return true; } 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 147dd7f7..78c3d4a2 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 @@ -2980,4 +2980,11 @@ + + select + setval('gepafin_schema.ndganag_id_seq', (select + max(id)+1 + from gepafin_schema.ndganag), false) + + From 6f7acbcdfeeee0271b7b8c12496f1400a9041942 Mon Sep 17 00:00:00 2001 From: rajesh Date: Wed, 3 Sep 2025 21:00:49 +0530 Subject: [PATCH 21/75] Updated configuration --- src/main/resources/application.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 4cb55816..ed60af77 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -27,8 +27,8 @@ springdoc.swagger-ui.tagsSorter=alpha call.id=10 #aws configuration -aws.access.key.id=AKIAVWDQWCUEOSUN4LUW -aws.secret.access.key=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 +aws.access.key.id=AKIAVWDQWCUENKE7QGXP +aws.secret.access.key=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 aws.s3.region=eu-west-1 aws.s3.bucket.name=mementoresources aws.s3.url = https://mementoresources.s3.eu-west-1.amazonaws.com/ From 94a3095ab35f2d83b3623006897f0e1ed5dc7b6a Mon Sep 17 00:00:00 2001 From: rajesh Date: Wed, 10 Sep 2025 17:42:04 +0530 Subject: [PATCH 22/75] Applied check for PEC email --- .../gepafin/tendermanagement/constants/GepafinConstant.java | 2 ++ .../net/gepafin/tendermanagement/dao/ApplicationDao.java | 5 +++++ src/main/resources/message_en.properties | 1 + src/main/resources/message_it.properties | 1 + 4 files changed, 9 insertions(+) diff --git a/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java b/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java index 888a3ed5..1d798996 100644 --- a/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java +++ b/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java @@ -577,6 +577,8 @@ public class GepafinConstant { public static final String COMPANY_NAME_JSON="denominazione"; public static final String USER_REQUEST_COMPLETED="user.request.completed"; public static final String END_DATE_GREATER_THAN_NOW="end.date.greater.than.now"; + public static final String PEC_EMAIL_IS_REQUIRED = "pec.email.required"; + } diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java index 4567d8b2..606df436 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java @@ -1493,6 +1493,11 @@ public class ApplicationDao { log.warn("Invalid amount requested | amount: {}", applicationEntity.getAmountRequested()); throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.AMOUNT_REQUEST_SHOULD_GREATED_THEN_ZERO)); } + + if (StringUtils.isEmpty(applicationEntity.getPecEmail())) { + log.warn("PEC email is required"); + throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.PEC_EMAIL_IS_REQUIRED)); + } List flowEdgesList = flowEdgesRepository.findByCallId(applicationEntity.getCall().getId()); Long totalSteps = flowFormDao.calculateTotalSteps(flowEdgesList); Integer completedSteps = flowFormDao.getCompletedSteps(applicationEntity, true); diff --git a/src/main/resources/message_en.properties b/src/main/resources/message_en.properties index ad25a88b..684a6006 100644 --- a/src/main/resources/message_en.properties +++ b/src/main/resources/message_en.properties @@ -412,4 +412,5 @@ ndg.not.found=NDG not found. email.pec.cannot.null=Email pec is required. user.request.completed=User request completed successfully. end.date.greater.than.now=End date must be greater than the current date and time. +pec.email.required=PEC email is required. diff --git a/src/main/resources/message_it.properties b/src/main/resources/message_it.properties index f98e55b8..92a96cb0 100644 --- a/src/main/resources/message_it.properties +++ b/src/main/resources/message_it.properties @@ -403,4 +403,5 @@ ndg.not.found=NDG non trovato. email.pec.cannot.null=L'indirizzo email pec obbligatorio. user.request.completed=Richiesta utente completata con successo. end.date.greater.than.now=La data di fine deve essere successiva alla data e all'ora correnti. +pec.email.required=Obbligatorio l'indirizzo e-mail PEC. From 956f20404c38062e1d8eb6498aac6604c4f9304a Mon Sep 17 00:00:00 2001 From: rajesh Date: Thu, 11 Sep 2025 15:37:06 +0530 Subject: [PATCH 23/75] Removed check form application for PEC --- .../net/gepafin/tendermanagement/dao/ApplicationDao.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java index 606df436..4567d8b2 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java @@ -1493,11 +1493,6 @@ public class ApplicationDao { log.warn("Invalid amount requested | amount: {}", applicationEntity.getAmountRequested()); throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.AMOUNT_REQUEST_SHOULD_GREATED_THEN_ZERO)); } - - if (StringUtils.isEmpty(applicationEntity.getPecEmail())) { - log.warn("PEC email is required"); - throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.PEC_EMAIL_IS_REQUIRED)); - } List flowEdgesList = flowEdgesRepository.findByCallId(applicationEntity.getCall().getId()); Long totalSteps = flowFormDao.calculateTotalSteps(flowEdgesList); Integer completedSteps = flowFormDao.getCompletedSteps(applicationEntity, true); From d057b8bd61481e7d7b00847acd20f8eb4bc4de8a Mon Sep 17 00:00:00 2001 From: rajesh Date: Fri, 12 Sep 2025 15:24:31 +0530 Subject: [PATCH 24/75] Fixed PDF spacing issue --- .../gepafin/tendermanagement/dao/PdfDao.java | 46 +++++++++++++------ src/main/resources/application.properties | 2 +- 2 files changed, 33 insertions(+), 15 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java b/src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java index afde01ab..d1ed9317 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java @@ -40,7 +40,7 @@ import java.util.stream.Collectors; @Component public class PdfDao { - @Value("${default.hub.pdf.banner}") + @Value("${default.pdf.banner}") private String defaultLogoUrl; @Autowired @@ -77,16 +77,20 @@ public class PdfDao { // CustomPageEvent pageEvent = new CustomPageEvent(call.getName(), 0); // writer.setPageEvent(pageEvent); document.open(); - String logoUrl=defaultLogoUrl; + String logoUrl=null; Optional hubEntity=hubRepository.findById(applicationEntity.getHubId()); - if(hubEntity.isPresent()) { + if (Boolean.TRUE.equals(validator.isProductionProfileActivated()) && applicationEntity.getCall().getId().equals(23l)) { + logoUrl=defaultLogoUrl; + } + else if(hubEntity.isPresent()) { if (hubEntity.get().getUniqueUuid().equals("p4lk3bcx1RStqTaIVVbXs")) { defaultLogoUrl = hubEntity.get().getPdfBanner(); } if (hubEntity.get().getUniqueUuid().equals("t7jh5wfg9QXylNaTZkPoE")) { defaultLogoUrl = hubEntity.get().getPdfBanner(); } + logoUrl=defaultLogoUrl; } // pageEvent.setTotalPages(writer.getPageNumber()); // addLogo(document, "logo.jpg"); // Add your image path here the migration code after cherry-pick @@ -112,7 +116,7 @@ public class PdfDao { ApplicationGetResponseBean applicationGetResponseBean=applicationDao.getApplicationByFormId(request, applicationId, null); for(FormApplicationResponse formApplicationResponse: applicationGetResponseBean.getForm()) { - List fieldLabelValuePairRequests = getFormFieldsToLabels(formApplicationResponse,writer,document); + List fieldLabelValuePairRequests = getFormFieldsToLabels(formApplicationResponse,writer,document,applicationEntity); addColoredLines(writer,document,greenColor); document.add(new Paragraph(" ")); // Add line break } @@ -132,10 +136,16 @@ public class PdfDao { return null; } - private void addLabelValuePair(PdfWriter writer,Document document, String label, Object value, Font labelFont,Font valueFont,ContentResponseBean contentResponseBean) throws DocumentException { + private void addLabelValuePair(PdfWriter writer,Document document, String label, Object value, Font labelFont,Font valueFont,ContentResponseBean contentResponseBean, ApplicationEntity applicationEntity) throws DocumentException { // Add label Map stateFieldMap= new HashMap<>(); - + if (Boolean.TRUE.equals(validator.isProductionProfileActivated()) && applicationEntity.getCall().getId().equals(23l)) { + for (SettingResponseBean settingResponseBean : contentResponseBean.getSettings()) { + if (settingResponseBean.getName().equals("isRequestedAmount") && settingResponseBean.getValue().equals(Boolean.TRUE)) { + return; + } + } + } Paragraph labelParagraph = new Paragraph(label, labelFont); labelParagraph.setSpacingAfter(-10f); document.add(labelParagraph); @@ -151,10 +161,10 @@ public class PdfDao { // 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 - document.newPage(); - } // Add a gap between the label and value +// if (yPos <= 140) { +// // If xEnd is less than or equal to 200, generate a new page +// 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); @@ -268,6 +278,7 @@ public class PdfDao { document.add(valueTable); } else { + if (value instanceof String) { String fieldValue1 = (String) value; if (Utils.isValidDateString(fieldValue1)) { @@ -503,7 +514,7 @@ public class PdfDao { canvas.stroke(); } } - public List getFormFieldsToLabels(FormApplicationResponse responseBean,PdfWriter writer,Document document) { + public List getFormFieldsToLabels(FormApplicationResponse responseBean,PdfWriter writer,Document document,ApplicationEntity applicationEntity) { List labelValuePairs = new ArrayList<>(); Font labelFont = FontFactory.getFont(FontFactory.HELVETICA_BOLD, 12,new BaseColor(113,121,126)); // Light grey); @@ -521,7 +532,7 @@ public class PdfDao { String name = content.getName(); // Content name Object fieldValue = ""; - String contentLabel = content.getSettings().stream() + String contentLabel = content.getSettings().stream() .filter(setting -> "label".equals(setting.getName())) // Filter settings by name .map(SettingResponseBean::getValue) // Extract the value from the matching setting .map(Object::toString) // Convert the value to a string @@ -547,13 +558,20 @@ public class PdfDao { labelCell.setBorder(Rectangle.NO_BORDER); labelCell.setGrayFill(7); labelCell.setPadding(5); - labelParagraph.setSpacingAfter(-10f); + labelCell.setNoWrap(false); // wrap long text + labelCell.setUseAscender(true); + labelCell.setUseDescender(true); // allow text wrapping // Create a PdfPTable with 1 column and add the PdfPCell to it PdfPTable table = new PdfPTable(1); table.setWidthPercentage(100); table.addCell(labelCell); + table.setSplitLate(false); + table.setSplitRows(true); + table.setKeepTogether(false); + labelCell.setMinimumHeight(0); + labelParagraph.add(table); try { document.add(labelParagraph); @@ -618,7 +636,7 @@ public class PdfDao { if((contentLabel==null || StringUtils.isEmpty(contentLabel)) && (fieldValue==null || StringUtils.isEmpty(fieldValue.toString()))) { continue; } - addLabelValuePair(writer, document, contentLabel, fieldValue, labelFont, valueFont, content); + addLabelValuePair(writer, document, contentLabel, fieldValue, labelFont, valueFont, content,applicationEntity); } catch (DocumentException e) { log.error("Error checking object: " + e.getMessage(), e); diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index ed60af77..f2db0c1e 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -67,7 +67,7 @@ api.pecUrl=https://ws.pecmassiva.com application.amendment.expiration.days=30 default.email.signature=Gepafin S.p.a -default.hub.pdf.banner=https://mementoresources.s3.amazonaws.com/gepafin/staging/template/gepafin-logo.jpg +default.pdf.banner=https://mementoresources.s3.amazonaws.com/gepafin/production/template/gepafin-logo-only.jpg #feign client config spring.cloud.openfeign.client.config.default.connectTimeout=300000 From 2b666bb73e8ecc8497b608a862a12b1170c8285e Mon Sep 17 00:00:00 2001 From: rajesh Date: Tue, 16 Sep 2025 13:19:32 +0530 Subject: [PATCH 25/75] PDF logo fix --- .../java/net/gepafin/tendermanagement/dao/PdfDao.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java b/src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java index d1ed9317..6d379f2a 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java @@ -77,7 +77,7 @@ public class PdfDao { // CustomPageEvent pageEvent = new CustomPageEvent(call.getName(), 0); // writer.setPageEvent(pageEvent); document.open(); - String logoUrl=null; + String logoUrl=defaultLogoUrl; Optional hubEntity=hubRepository.findById(applicationEntity.getHubId()); if (Boolean.TRUE.equals(validator.isProductionProfileActivated()) && applicationEntity.getCall().getId().equals(23l)) { @@ -85,12 +85,12 @@ public class PdfDao { } else if(hubEntity.isPresent()) { if (hubEntity.get().getUniqueUuid().equals("p4lk3bcx1RStqTaIVVbXs")) { - defaultLogoUrl = hubEntity.get().getPdfBanner(); + logoUrl = hubEntity.get().getPdfBanner(); } if (hubEntity.get().getUniqueUuid().equals("t7jh5wfg9QXylNaTZkPoE")) { - defaultLogoUrl = hubEntity.get().getPdfBanner(); + logoUrl = hubEntity.get().getPdfBanner(); } - logoUrl=defaultLogoUrl; + } // pageEvent.setTotalPages(writer.getPageNumber()); // addLogo(document, "logo.jpg"); // Add your image path here the migration code after cherry-pick From 7f4daabf0525abf34cfac29a209d3650d904bcff Mon Sep 17 00:00:00 2001 From: rajesh Date: Tue, 16 Sep 2025 13:35:21 +0530 Subject: [PATCH 26/75] Resize logo --- .../net/gepafin/tendermanagement/dao/PdfDao.java | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java b/src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java index 6d379f2a..233ced7a 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java @@ -94,7 +94,7 @@ public class PdfDao { } // pageEvent.setTotalPages(writer.getPageNumber()); // addLogo(document, "logo.jpg"); // Add your image path here the migration code after cherry-pick - addLogo(document, logoUrl); + addLogo(document, logoUrl,applicationEntity); BaseColor customColor = new BaseColor(0, 128, 0); // Adjust RGB values as needed @@ -672,10 +672,15 @@ public class PdfDao { return valueToFind; } - public void addLogo(Document document, String logoPath) throws Exception { + public void addLogo(Document document, String logoPath,ApplicationEntity applicationEntity) 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) + if (Boolean.TRUE.equals(validator.isProductionProfileActivated()) && applicationEntity.getCall().getId().equals(23l)) { + logo.scaleToFit(120, 60); + } + else { + 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); From d877db39fa97ff4383cc652d52c5e30c9f9a3c6f Mon Sep 17 00:00:00 2001 From: rajesh Date: Tue, 16 Sep 2025 18:13:24 +0530 Subject: [PATCH 27/75] Updated mail content for specific hub --- .../constants/GepafinConstant.java | 17 +++++++++++++++++ .../tendermanagement/dao/ApplicationDao.java | 12 +++++++++++- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java b/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java index 1d798996..0643a076 100644 --- a/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java +++ b/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java @@ -578,6 +578,23 @@ public class GepafinConstant { public static final String USER_REQUEST_COMPLETED="user.request.completed"; public static final String END_DATE_GREATER_THAN_NOW="end.date.greater.than.now"; public static final String PEC_EMAIL_IS_REQUIRED = "pec.email.required"; + public static final String APPLICATION_SUBMISSION_MAIL_BODY="\n" + + "\n" + + "
\n" + + "

Buongiorno,

\n" + + "

\n" + + " Si comunica che, il “Modello AR1“ di cui all'oggetto, è stato regolarmente acquisito ed è stato registrato con Protocollo n. \n" + + " {{protocol_number}} del {{date}} alle \n" + + " {{time}}.\n" + + "

\n" + + "

Distinti Saluti,

\n" + + "

\n" + + " {{email_signature}}\n" + + "

\n" + + "
\n" + + "\n" + + ""; + public static final String APPLICATION_SUBMISSION_MAIL_SUBJECT="Modello AR1 GARANZIA PARTECIPAZIONI E FINANZIAMENTI S.P.A. - PER BREVITA' GEPAFIN S.P.A"; } diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java index 4567d8b2..be657c02 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java @@ -222,6 +222,9 @@ public class ApplicationDao { @Autowired private CallRepository callRepository; + @Autowired + private SystemEmailTemplatesDao systemEmailTemplatesDao; + public final Random random = new Random(); public ApplicationResponseBean createApplication(HttpServletRequest request, ApplicationRequestBean applicationRequestBean, Long formId, Long applicationId) { @@ -1199,8 +1202,13 @@ public class ApplicationDao { SystemEmailTemplateResponse systemEmailTemplateResponse = systemEmailTemplatesService .retrieveTemplateByTypeAndCall(SystemEmailTemplatesEntityTypeEnum.APPLICATION_SUBMISSION_TO_USER_AND_COMPANY, hub, null); + if (Boolean.TRUE.equals(validator.isProductionProfileActivated()) && applicationEntity.getCall().getId().equals(23l)) { + systemEmailTemplateResponse.setHtmlContent(GepafinConstant.APPLICATION_SUBMISSION_MAIL_BODY); + systemEmailTemplateResponse.setHtmlContent(systemEmailTemplatesDao.replaceEmailSignature(hub,GepafinConstant.APPLICATION_SUBMISSION_MAIL_BODY,null)); + systemEmailTemplateResponse.setSubject(GepafinConstant.APPLICATION_SUBMISSION_MAIL_SUBJECT); + } - // Create the map for subject placeholders + // Create the map for subject placeholders Map subjectPlaceholders = new HashMap<>(); subjectPlaceholders.put("{{call_name}}", call.getName()); subjectPlaceholders.put("{{company_name}}", company.getCompanyName()); @@ -1272,6 +1280,8 @@ public class ApplicationDao { .retrieveTemplateByTypeAndCall(SystemEmailTemplatesEntityTypeEnum.APPLICATION_SUBMISSION_TO_GEPAFIN, hub, null); + + // Create the map for subject placeholders Map subjectPlaceholders = new HashMap<>(); subjectPlaceholders.put("{{call_name}}", call.getName()); From 446b304e7533915d8c1abd7753e654e8b4c26179 Mon Sep 17 00:00:00 2001 From: rajesh Date: Wed, 17 Sep 2025 16:50:53 +0530 Subject: [PATCH 28/75] Amendment request mail changes --- .../constants/GepafinConstant.java | 21 ++++++++++++++++++- .../dao/EmailNotificationDao.java | 10 +++++++-- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java b/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java index 0643a076..b6b5f637 100644 --- a/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java +++ b/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java @@ -595,7 +595,26 @@ public class GepafinConstant { "\n" + ""; public static final String APPLICATION_SUBMISSION_MAIL_SUBJECT="Modello AR1 GARANZIA PARTECIPAZIONI E FINANZIAMENTI S.P.A. - PER BREVITA' GEPAFIN S.P.A"; - + public static final String APPLICATION_AMENDMENT_REQUESTED_MAIL_BODY="\n" + + " \n" + + "
\n" + + "

DOCUMENTALE

\n" + + "

Buongiorno,

\n" + + "

In riferimento al questionario antiriciclaggio\n" + + " “{{call_name}}“ di cui al Protocollo n. {{protocol_number}} del\n" + + " {{protocol_date}} e {{protocol_time}}, alla luce dell'attività istruttoria svolta,\n" + + " segnaliamo quanto segue:\n" + + "

\n" + + " {{note}}\n" + + "

Vi invitiamo a fornire quanto sopra richiesto integrando la documentazione sia caricandola all'interno dello sportello\n" + + " online {{platform_link}} che inviandola a mezzo PEC all'indirizzo\n" + + " bandi.gepafin@legalmail.it entro e non oltre {{response_days}} giorni \n" + + "

\n" + + "

Distinti Saluti,

\n" + + "

{{email_signature}}

\n" + + "
\n" + + " \n" + + ""; } diff --git a/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java index 462958cb..a556d042 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java @@ -18,6 +18,7 @@ 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.Utils; +import net.gepafin.tendermanagement.util.Validator; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -76,6 +77,9 @@ public class EmailNotificationDao { @Autowired private SystemEmailTemplatesDao systemEmailTemplatesDao; + @Autowired + private Validator validator; + private void sendEmail(ApplicationEntity applicationEntity, SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum templateType, Map bodyPlaceholders, List additionalRecipients, Long amendmentId) { @@ -95,8 +99,10 @@ public class EmailNotificationDao { Map bodyPlaceholders ) { SystemEmailTemplateResponse systemEmailTemplateResponse = systemEmailTemplatesService.retrieveTemplateByTypeAndCall(templateType, hubEntity, null); - - Map subjectPlaceholders = new HashMap<>(); + if(Boolean.TRUE.equals(templateType.equals(SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum.DOCUMENTATION_INTEGRATION_REQUEST)) && Boolean.TRUE.equals(validator.isProductionProfileActivated()) && applicationEntity.getCall().getId().equals(23l)) { + systemEmailTemplateResponse.setHtmlContent(systemEmailTemplatesDao.replaceEmailSignature(hubEntity,GepafinConstant.APPLICATION_AMENDMENT_REQUESTED_MAIL_BODY,null)); + } + Map subjectPlaceholders = new HashMap<>(); CompanyEntity company = companyService.validateCompany(applicationEntity.getCompanyId()); subjectPlaceholders.put("{{call_name}}", applicationEntity.getCall().getName()); subjectPlaceholders.put("{{company_name}}", company.getCompanyName()); From 8aa7665a64a25c1f341482676b49672feba5a33c Mon Sep 17 00:00:00 2001 From: rajesh Date: Thu, 18 Sep 2025 11:54:29 +0530 Subject: [PATCH 29/75] Updated email content for properties --- .../net/gepafin/tendermanagement/dao/ApplicationDao.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java index be657c02..e97f0339 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java @@ -1280,7 +1280,11 @@ public class ApplicationDao { .retrieveTemplateByTypeAndCall(SystemEmailTemplatesEntityTypeEnum.APPLICATION_SUBMISSION_TO_GEPAFIN, hub, null); - + if (Boolean.TRUE.equals(validator.isProductionProfileActivated()) && applicationEntity.getCall().getId().equals(23l)) { + systemEmailTemplateResponse.setHtmlContent(GepafinConstant.APPLICATION_SUBMISSION_MAIL_BODY); + systemEmailTemplateResponse.setHtmlContent(systemEmailTemplatesDao.replaceEmailSignature(hub,GepafinConstant.APPLICATION_SUBMISSION_MAIL_BODY,null)); + systemEmailTemplateResponse.setSubject(GepafinConstant.APPLICATION_SUBMISSION_MAIL_SUBJECT); + } // Create the map for subject placeholders Map subjectPlaceholders = new HashMap<>(); From f2612aa07b76d59375896a22ba2de388418f8bd3 Mon Sep 17 00:00:00 2001 From: rajesh Date: Fri, 19 Sep 2025 17:13:06 +0530 Subject: [PATCH 30/75] Saved PEC in application while validating --- .../net/gepafin/tendermanagement/dao/FormDao.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/FormDao.java b/src/main/java/net/gepafin/tendermanagement/dao/FormDao.java index 8ce395d0..06811619 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/FormDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/FormDao.java @@ -1,6 +1,7 @@ package net.gepafin.tendermanagement.dao; import jakarta.servlet.http.HttpServletRequest; +import net.gepafin.tendermanagement.model.response.SettingResponseBean; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import net.gepafin.tendermanagement.config.Translator; @@ -488,7 +489,17 @@ public class FormDao { FieldValidatorBean fieldValidatorBean = Utils.convertSourceObjectToDestinationObject(contentResponseBean.getValidators(), FieldValidatorBean.class); String fieldValue = getFieldValue(contentResponseBean); + Map settingMap = contentResponseBean.getSettings().stream() + .collect(Collectors.toMap(SettingResponseBean::getName, SettingResponseBean::getValue, (v1, v2) -> v1)); + String fieldType = contentResponseBean.getName(); + if(Boolean.TRUE.equals(isSendValidationError)){ + if ("textinput".equals(fieldType) && Boolean.TRUE.equals(settingMap.get("isPecEmail"))) { + String pecEmail = (String) formFieldMap.get(contentResponseBean.getId()); + applicationEntity.setPecEmail(pecEmail); + } + log.info("Set PEC to {} for Application ID: {}", fieldValue, applicationEntity.getId()); + } validator.isRequired(value, fieldValidatorBean.getIsRequired(), fieldValue) .validateCustomTableValidation(value,fieldValidatorBean.getCustom(),fieldValue,contentResponseBean); }); From 17f03f13ba92c21912df1d3de5de85c9827d0fcb Mon Sep 17 00:00:00 2001 From: rajesh Date: Fri, 19 Sep 2025 17:13:53 +0530 Subject: [PATCH 31/75] Updated code --- .../net/gepafin/tendermanagement/dao/ApplicationDao.java | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java index e97f0339..02963812 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java @@ -613,13 +613,7 @@ public class ApplicationDao { throw new IllegalArgumentException("Field value is not a valid number: " + fieldValue, e); } } - - // Add handler for isPecEmail - if ("textinput".equals(fieldType) && Boolean.TRUE.equals(settingMap.get("isPecEmail"))) { - applicationFormEntity.getApplication().setPecEmail(fieldValue.toString()); - log.info("Set PEC to {} for Application ID: {}", fieldValue, applicationFormEntity.getApplication().getId()); - } - + if ("textinput".equals(fieldType) && Boolean.TRUE.equals(settingMap.get("isPIVA"))) { applicationFormEntity.getApplication().setVatNumber(fieldValue.toString()); log.info("Set PEC to {} for Application ID: {}", fieldValue, applicationFormEntity.getApplication().getId()); From f5bf0f31af627241d025d2147c485f47203f0df8 Mon Sep 17 00:00:00 2001 From: rajesh Date: Fri, 26 Sep 2025 20:04:01 +0530 Subject: [PATCH 32/75] Fixed issue in assigned application --- .../tendermanagement/dao/ApplicationEvaluationDao.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java index 1ccc1664..fec8882c 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java @@ -612,8 +612,8 @@ public class ApplicationEvaluationDao { CallEntity call = callRepository.findCallEntityByApplicationId(entity.getApplicationId()); - String firstName = user.getBeneficiary().getFirstName() != null ? user.getBeneficiary().getFirstName() : ""; - String lastName = user.getBeneficiary().getLastName() != null ? user.getBeneficiary().getLastName() : ""; + String firstName = user.getBeneficiary() != null ? user.getBeneficiary().getFirstName() : ""; + String lastName = user.getBeneficiary() != null ? user.getBeneficiary().getLastName() : ""; String beneficiary = String.join(" ", firstName, lastName).trim(); response.setApplicationStatus(ApplicationStatusTypeEnum.valueOf(application.getStatus())); response.setBeneficiary(beneficiary); From 47db22e69c2a3f80f4ea6f970cea6a8146dd5517 Mon Sep 17 00:00:00 2001 From: rajesh Date: Fri, 26 Sep 2025 20:04:33 +0530 Subject: [PATCH 33/75] Handled notification --- .../tendermanagement/dao/NotificationDao.java | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/NotificationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/NotificationDao.java index 55ec6665..57236418 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/NotificationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/NotificationDao.java @@ -29,6 +29,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.jpa.domain.Specification; +import org.springframework.messaging.MessagingException; import org.springframework.messaging.simp.SimpMessagingTemplate; import org.springframework.stereotype.Component; @@ -105,7 +106,11 @@ public class NotificationDao { String userChannel = GepafinConstant.COMMON_SINGLE_CHANNEL_PREFIX + userId; log.info("Channel for User {}", userChannel); NotificationResponse notificationResponse = convertNotificationEntityToNotificationResponse(notificationEntity); - messagingTemplate.convertAndSend(userChannel, notificationResponse); + try { + messagingTemplate.convertAndSend(userChannel, notificationResponse); + } catch (Exception e) { + log.error("Error while sending the notification {0}", e); + } } private void sendToCompanies(Long userId, List companyIds, NotificationEntity notificationEntity) { @@ -120,7 +125,11 @@ public class NotificationDao { notificationEntity.setUserWithCompany(userWithCompany); notificationRepository.save(notificationEntity); NotificationResponse notificationResponse = convertNotificationEntityToNotificationResponse(notificationEntity); - messagingTemplate.convertAndSend(companyChannel, notificationResponse); + try { + messagingTemplate.convertAndSend(companyChannel, notificationResponse); + } catch (Exception e) { + log.error("Error while sending the notification {0}", e); + } }); } From baa7ea8d55bd9572aa264289a518421ac6b66ef0 Mon Sep 17 00:00:00 2001 From: rajesh Date: Tue, 30 Sep 2025 20:24:55 +0530 Subject: [PATCH 34/75] Done ticket GEPAFINBE-236 --- .../dao/ApplicationAmendmentRequestDao.java | 164 +++++++++++++----- .../dao/ApplicationEvaluationDao.java | 12 +- .../dao/EmailNotificationDao.java | 61 ++++++- .../dao/EvaluationFormDao.java | 2 +- .../ApplicationAmendmentRequestEntity.java | 6 + .../entities/SystemEmailTemplatesEntity.java | 3 +- .../enums/AmendmentDocumentTypeEnum.java | 26 +++ .../ApplicationAmendmentRequestTypeEnum.java | 22 +++ .../enums/ApplicationStatusForEvaluation.java | 1 + .../enums/EmailScenarioTypeEnum.java | 3 +- .../enums/UserActionContextEnum.java | 3 +- .../ApplicationAmendmentSpecialRequest.java | 16 ++ .../model/request/AttachmentRequest.java | 11 ++ .../model/request/EmailLogRequest.java | 4 + .../model/request/PecEmailRequest.java | 1 + .../repositories/DocumentRepository.java | 2 + .../ApplicationAmendmentRequestService.java | 7 +- ...pplicationAmendmentRequestServiceImpl.java | 11 +- .../service/impl/PecEmailService.java | 6 +- .../util/S3DocxProcessor.java | 140 +++++++++++++++ .../gepafin/tendermanagement/util/Utils.java | 27 +-- .../api/ApplicationAmendmentRequestApi.java | 13 ++ ...ApplicationAmendmentRequestController.java | 11 ++ src/main/resources/application.properties | 2 +- .../db/changelog/db.changelog-1.0.0.xml | 13 ++ .../insert_document_for_special_amendment.sql | 23 +++ ...plate_for_special_amendment_28-09-2025.sql | 11 ++ 27 files changed, 524 insertions(+), 77 deletions(-) create mode 100644 src/main/java/net/gepafin/tendermanagement/enums/AmendmentDocumentTypeEnum.java create mode 100644 src/main/java/net/gepafin/tendermanagement/enums/ApplicationAmendmentRequestTypeEnum.java create mode 100644 src/main/java/net/gepafin/tendermanagement/model/request/ApplicationAmendmentSpecialRequest.java create mode 100644 src/main/java/net/gepafin/tendermanagement/model/request/AttachmentRequest.java create mode 100644 src/main/java/net/gepafin/tendermanagement/util/S3DocxProcessor.java create mode 100644 src/main/resources/db/dump/insert_document_for_special_amendment.sql create mode 100644 src/main/resources/db/dump/insert_system_email_template_for_special_amendment_28-09-2025.sql 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 From d2f0fb1463bca46a13b8724929b8357ae0b8275b Mon Sep 17 00:00:00 2001 From: rajesh Date: Wed, 1 Oct 2025 12:37:01 +0530 Subject: [PATCH 35/75] Fixed issue in evalaution api for new amendment --- .../tendermanagement/enums/ApplicationStatusTypeEnum.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/gepafin/tendermanagement/enums/ApplicationStatusTypeEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/ApplicationStatusTypeEnum.java index 3afbc3ad..fd48ab9a 100644 --- a/src/main/java/net/gepafin/tendermanagement/enums/ApplicationStatusTypeEnum.java +++ b/src/main/java/net/gepafin/tendermanagement/enums/ApplicationStatusTypeEnum.java @@ -17,7 +17,8 @@ public enum ApplicationStatusTypeEnum { NDG("NDG"), ADMISSIBLE("ADMISSIBLE"), TECHNICAL_EVALUATION("TECHNICAL_EVALUATION"), - TECHNICAL_EVALUATION_REJECTED("TECHNICAL_EVALUATION_REJECTED"); + TECHNICAL_EVALUATION_REJECTED("TECHNICAL_EVALUATION_REJECTED"), + AWAITING_TECHNICAL_EVALUATION("AWAITING_TECHNICAL_EVALUATION") ; private String value; From 68e4d57e72ec3903d77b24885246301066096095 Mon Sep 17 00:00:00 2001 From: rajesh Date: Wed, 1 Oct 2025 13:16:18 +0530 Subject: [PATCH 36/75] Fixed issue in new amendment --- .../dao/ApplicationAmendmentRequestDao.java | 16 +++++++++++----- src/main/resources/application-dev.properties | 2 +- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java index 080ed3d1..2ab22d1f 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java @@ -735,13 +735,19 @@ public class ApplicationAmendmentRequestDao { ApplicationAmendmentRequestEntity oldApplicationAmendmentEntity = Utils.getClonedEntityForData(existingApplicationAmendment); setIfUpdated(existingApplicationAmendment::getNote, existingApplicationAmendment::setNote, updateRequest.getNote()); + Map amendmentFormFieldMap; + Map applicationFormFieldMap=null; + if(existingApplicationAmendment.getFormFields()!=null && Boolean.FALSE.equals(existingApplicationAmendment.getFormFields().isEmpty())) { + amendmentFormFieldMap = Utils + .convertJsonStringToList(existingApplicationAmendment.getFormFields(), AmendmentFormField.class) + .stream().collect(Collectors.toMap(AmendmentFormField::getFieldId, Function.identity())); + applicationFormFieldMap = getApplicationFormFieldList(existingApplicationAmendment, amendmentFormFieldMap.keySet().stream().toList()).stream().collect(Collectors.toMap(ApplicationFormFieldEntity::getFieldId, Function.identity())); - Map amendmentFormFieldMap = Utils - .convertJsonStringToList(existingApplicationAmendment.getFormFields(), AmendmentFormField.class) - .stream().collect(Collectors.toMap(AmendmentFormField::getFieldId, Function.identity())); - Map applicationFormFieldMap = getApplicationFormFieldList(existingApplicationAmendment, amendmentFormFieldMap.keySet().stream().toList()).stream().collect(Collectors.toMap(ApplicationFormFieldEntity::getFieldId, Function.identity())); + } else { + amendmentFormFieldMap = null; + } - if(updateRequest.getApplicationFormFields() != null) { + if(updateRequest.getApplicationFormFields() != null && amendmentFormFieldMap!=null) { updateRequest.getApplicationFormFields().stream().forEach(applicationFormFieldRequest->{ AmendmentFormField amendmentFormField = getAmendmentFormField(amendmentFormFieldMap,applicationFormFieldRequest.getFieldId()); // ApplicationFormFieldEntity applicationFormFieldEntity = getApplicationFormField(applicationFormFieldMap, applicationFormFieldRequest.getFieldId()); diff --git a/src/main/resources/application-dev.properties b/src/main/resources/application-dev.properties index bc453374..80e20599 100644 --- a/src/main/resources/application-dev.properties +++ b/src/main/resources/application-dev.properties @@ -10,7 +10,7 @@ spring.h2.console.enabled=true isVatCheckGloballyDisabled = false isMailSendingEnabled = true -isPecServiceEnabled = false +isPecServiceEnabled = true #default_System_Receiver_Email=antonio.manca@bflows.net gepafin_email=rinaldo.bonazzo@bflows.net rinaldo_email=rinaldo.bonazzo@bflows.net From 129c0a59df10b1e1a1dab3a248af403af08da73a Mon Sep 17 00:00:00 2001 From: rajesh Date: Wed, 1 Oct 2025 19:01:20 +0530 Subject: [PATCH 37/75] Fixed issue in closing amendment --- .../tendermanagement/dao/ApplicationAmendmentRequestDao.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java index 080ed3d1..1fea4d1d 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java @@ -1109,7 +1109,9 @@ public class ApplicationAmendmentRequestDao { applicationEvaluationRepository.save(existingApplicationAmendment.getApplicationEvaluationEntity()); log.info("Updated ApplicationEvaluation status to OPEN for ID: {}", existingApplicationEvaluationEntity.getId()); - application.setStatus(ApplicationStatusTypeEnum.EVALUATION.getValue()); + if(Boolean.FALSE.equals(existingApplicationAmendment.getType().equals(ApplicationAmendmentRequestTypeEnum.SPECIAL.getValue()))){ + application.setStatus(ApplicationStatusTypeEnum.EVALUATION.getValue()); + } applicationRepository.save(application); log.info("Updated Application status to EVALUATION for Application ID: {}", application.getId()); From 2e0b033128df9f60349ccc609c306dbaff5244f7 Mon Sep 17 00:00:00 2001 From: rajesh Date: Thu, 2 Oct 2025 13:02:31 +0530 Subject: [PATCH 38/75] Updated code for pec --- .../tendermanagement/dao/ApplicationAmendmentRequestDao.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java index 1318fe37..57222c69 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java @@ -1833,7 +1833,7 @@ public class ApplicationAmendmentRequestDao { if (applicationAmendmentRequest.getAmount() != null && (amountAccepted==null || applicationAmendmentRequest.getAmount().compareTo(amountAccepted) == 0)) { applicationEntity.setAmountAccepted(applicationAmendmentRequest.getAmount()); } - if(Boolean.FALSE.equals(applicationAmendmentRequest.getPec().equals(applicationEntity.getPecEmail()))){ + if(Boolean.FALSE.equals(StringUtils.isEmpty(applicationAmendmentRequest.getPec())) && Boolean.FALSE.equals(applicationAmendmentRequest.getPec().equals(applicationEntity.getPecEmail()))){ applicationEntity.setPecEmail(applicationAmendmentRequest.getPec()); } applicationEvaluationDao.processTechnicalEvaluation(applicationEntity.getId(),applicationEntity,ApplicationStatusForEvaluation.AWAITING_TECHNICAL_EVALUATION,applicationEvaluationEntity); From 2629df5c29f42bb4bda69a569acda175cbd29466 Mon Sep 17 00:00:00 2001 From: rajesh Date: Mon, 6 Oct 2025 15:43:59 +0530 Subject: [PATCH 39/75] Updated code for score checking --- .../gepafin/tendermanagement/dao/ApplicationEvaluationDao.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java index 0d11aee0..d53643ea 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java @@ -2571,7 +2571,7 @@ public class ApplicationEvaluationDao { String criteriaJson = evaluationEntity.getCriteria(); if (criteriaJson != null){ BigDecimal totalScore = calculateTotalScore(evaluationEntity.getCriteria()); - if (totalScore.compareTo(new BigDecimal("40")) > 0) { + if (totalScore.compareTo(new BigDecimal("40")) >= 0) { applicationEntity.setStatus(status.getValue()); log.info("Status updated to AWAITING_TECHNICAL_EVALUATION for applicationId: {}", applicationId); } From 1f6bcad5ebbb3e64d82eedb796ec63cacf42b419 Mon Sep 17 00:00:00 2001 From: rajesh Date: Mon, 6 Oct 2025 18:45:39 +0530 Subject: [PATCH 40/75] Updated code --- src/main/resources/application.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index e1d0cba5..f2db0c1e 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=local +spring.profiles.active=testing # JPA Configuration From 4d7e7e33ba2b20940a3041a7d74988660cd69975 Mon Sep 17 00:00:00 2001 From: rajesh Date: Mon, 6 Oct 2025 18:47:33 +0530 Subject: [PATCH 41/75] Updated code for score checking --- .../gepafin/tendermanagement/dao/ApplicationEvaluationDao.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java index d53643ea..e5740a4f 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java @@ -2571,7 +2571,7 @@ public class ApplicationEvaluationDao { String criteriaJson = evaluationEntity.getCriteria(); if (criteriaJson != null){ BigDecimal totalScore = calculateTotalScore(evaluationEntity.getCriteria()); - if (totalScore.compareTo(new BigDecimal("40")) >= 0) { + if (totalScore.compareTo(new BigDecimal(applicationEntity.getCall().getThreshold())) >= 0) { applicationEntity.setStatus(status.getValue()); log.info("Status updated to AWAITING_TECHNICAL_EVALUATION for applicationId: {}", applicationId); } From 2bf9fe368c9096338c3c6ad33f5ba20f10b1cf73 Mon Sep 17 00:00:00 2001 From: rajesh Date: Mon, 6 Oct 2025 19:17:28 +0530 Subject: [PATCH 42/75] Updated code --- .../gepafin/tendermanagement/dao/ApplicationEvaluationDao.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java index e5740a4f..cf135a24 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java @@ -2569,7 +2569,7 @@ public class ApplicationEvaluationDao { 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){ + if (criteriaJson != null && applicationEntity.getCall().getThreshold()!=null ){ BigDecimal totalScore = calculateTotalScore(evaluationEntity.getCriteria()); if (totalScore.compareTo(new BigDecimal(applicationEntity.getCall().getThreshold())) >= 0) { applicationEntity.setStatus(status.getValue()); From e5d5cdac2e84966941e26d28374b41ead975f674 Mon Sep 17 00:00:00 2001 From: rajesh Date: Tue, 7 Oct 2025 15:01:30 +0530 Subject: [PATCH 43/75] Updated logic for amendment --- .../dao/ApplicationAmendmentRequestDao.java | 35 +++++++++++-------- .../entities/ApplicationEntity.java | 2 ++ .../ApplicationAmendmentScheduler.java | 2 +- .../db/changelog/db.changelog-1.0.0.xml | 5 +++ 4 files changed, 28 insertions(+), 16 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java index 57222c69..2321507f 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java @@ -337,6 +337,7 @@ public class ApplicationAmendmentRequestDao { applicationAmendmentRequestEntity.setIsNotification(applicationAmendmentRequest.getIsSendNotification()); applicationAmendmentRequestEntity.setStartDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); applicationAmendmentRequestEntity.setStatus(ApplicationAmendmentRequestEnum.AWAITING.getValue()); + applicationAmendmentRequestEntity.setType(ApplicationAmendmentRequestTypeEnum.REGULAR.getValue()); ApplicationEvaluationEntity applicationEvaluationEntity = applicationEvaluationService.validateApplicationEvaluation(applicationEvaluationId); //cloned for old data entity ApplicationEvaluationEntity oldApplicationEvaluationEntity = Utils.getClonedEntityForData(applicationEvaluationEntity); @@ -345,7 +346,8 @@ public class ApplicationAmendmentRequestDao { Long applicationId = applicationEvaluationEntity.getApplicationId(); Long assignedApplicationId = applicationEvaluationEntity.getAssignedApplicationsEntity().getId(); applicationAmendmentRequestEntity.setApplicationId(applicationId); - + ApplicationEntity applicationEntity = applicationService.validateApplication(applicationId); + ApplicationEntity oldApplicationEntity = Utils.getClonedEntityForData(applicationEntity); if (applicationAmendmentRequest.getFormFields() != null) { List formFieldRequestBean = applicationAmendmentRequest.getFormFields().stream() .filter(AmendmentFormFieldResponse::isSelected) @@ -362,18 +364,22 @@ public class ApplicationAmendmentRequestDao { } List amendmentRequest = applicationAmendmentRequestRepository.findAllByApplicationEvaluationIdAndIsDeletedFalse(applicationEvaluationEntity.getId()); // Ensure startDate and initialDays are not null to avoid NullPointerException - if (amendmentRequest !=null && amendmentRequest.isEmpty() && 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())); + if (amendmentRequest !=null && amendmentRequest.isEmpty()) { + 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())); + } + applicationEntity.setPreviousStatus(oldApplicationEntity.getStatus()); } + UserEntity userEntity = userService.validateUser(applicationEvaluationEntity.getUserId()); Long protocolNumber = protocolDao.getProtocolNumber(userEntity.getHub()); ProtocolEntity protocolEntity = protocolDao.createProtocolEntity( @@ -396,8 +402,7 @@ public class ApplicationAmendmentRequestDao { loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplicationEvaluationEntity).newData(applicationEvaluationEntity).build()); } - ApplicationEntity applicationEntity = applicationService.validateApplication(applicationId); - ApplicationEntity oldApplicationEntity = Utils.getClonedEntityForData(applicationEntity); + String applicationStatusType = applicationEntity.getStatus(); if (Boolean.FALSE.equals(applicationStatusType.equals((ApplicationStatusTypeEnum.SOCCORSO.getValue())))) { applicationEntity.setStatus(ApplicationStatusTypeEnum.SOCCORSO.getValue()); @@ -1116,10 +1121,10 @@ public class ApplicationAmendmentRequestDao { log.info("Updated ApplicationEvaluation status to OPEN for ID: {}", existingApplicationEvaluationEntity.getId()); if(Boolean.FALSE.equals(existingApplicationAmendment.getType().equals(ApplicationAmendmentRequestTypeEnum.SPECIAL.getValue()))){ - application.setStatus(ApplicationStatusTypeEnum.EVALUATION.getValue()); + application.setStatus(application.getPreviousStatus()); } applicationRepository.save(application); - log.info("Updated Application status to EVALUATION for Application ID: {}", application.getId()); + log.info("Updated Application status to previous state for Application ID: {}", application.getId()); existingApplicationAmendment.getApplicationEvaluationEntity().getAssignedApplicationsEntity().setStatus(AssignedApplicationEnum.OPEN.getValue()); diff --git a/src/main/java/net/gepafin/tendermanagement/entities/ApplicationEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/ApplicationEntity.java index dacc3541..8a62c3b6 100644 --- a/src/main/java/net/gepafin/tendermanagement/entities/ApplicationEntity.java +++ b/src/main/java/net/gepafin/tendermanagement/entities/ApplicationEntity.java @@ -79,4 +79,6 @@ public class ApplicationEntity extends BaseEntity { @Column(name="VAT_NUMBER") private String vatNumber; + @Column(name = "PREVIOUS_STATUS") + private String previousStatus; } \ No newline at end of file diff --git a/src/main/java/net/gepafin/tendermanagement/scheduler/ApplicationAmendmentScheduler.java b/src/main/java/net/gepafin/tendermanagement/scheduler/ApplicationAmendmentScheduler.java index 050b4972..b96eb137 100644 --- a/src/main/java/net/gepafin/tendermanagement/scheduler/ApplicationAmendmentScheduler.java +++ b/src/main/java/net/gepafin/tendermanagement/scheduler/ApplicationAmendmentScheduler.java @@ -161,7 +161,7 @@ public class ApplicationAmendmentScheduler { public void updateApplicationStatus(ApplicationEntity applicationEntity){ ApplicationEntity oldApplicationEntity = Utils.getClonedEntityForData(applicationEntity); - applicationEntity.setStatus(ApplicationStatusTypeEnum.EVALUATION.getValue()); + applicationEntity.setStatus(applicationEntity.getPreviousStatus()); applicationRepository.save(applicationEntity); log.info("Updated status to EVALUATION for Application with ID: {}",applicationEntity.getId()); 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 d99cb334..949efad2 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 @@ -3035,4 +3035,9 @@ + + + + + From 82f172ca9a254328a36443b7e9ed25458b71081e Mon Sep 17 00:00:00 2001 From: rajesh Date: Wed, 8 Oct 2025 16:21:04 +0530 Subject: [PATCH 44/75] Updated appointment password --- src/main/resources/application-production.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/application-production.properties b/src/main/resources/application-production.properties index ef5f73f2..b159155c 100644 --- a/src/main/resources/application-production.properties +++ b/src/main/resources/application-production.properties @@ -26,7 +26,7 @@ default.hub.uuid=p4lk3bcx1RStqTaIVVbXs #Login to Odessa, Appointment Creation, Upload document Configuration appointment.base.url=https://prd.galileonetwork.it/gateway/rest appointment.portal.user=UtenzaAPIPortal@621 -appointment.portal.password=Valeria2016!! +appointment.portal.password=Valeria2016! appointment.portal.source=GEPAFINPORTAL appointment.portal.context=GEPAFINPORTAL From 38515ed38b6ea122178fe1ced7faf32f46ae3fc8 Mon Sep 17 00:00:00 2001 From: rajesh Date: Mon, 13 Oct 2025 21:50:26 +0530 Subject: [PATCH 45/75] Done ticket GEPAFINBE-6139 --- .../constants/GepafinConstant.java | 8 + .../dao/ApplicationAmendmentRequestDao.java | 150 +++++++++++------- .../tendermanagement/dao/ApplicationDao.java | 50 +++++- .../dao/ApplicationEvaluationDao.java | 59 +++++-- .../tendermanagement/dao/AppointmentDao.java | 1 + .../gepafin/tendermanagement/dao/CallDao.java | 2 +- .../dao/CommunicationDao.java | 70 +++++++- .../dao/CompanyDocumentDao.java | 2 +- .../tendermanagement/dao/DelegationDao.java | 2 +- .../tendermanagement/dao/DocumentDao.java | 36 ++++- .../dao/EmailNotificationDao.java | 58 +++++-- .../tendermanagement/dao/S3PathConfig.java | 13 +- .../ApplicationAmendmentRequestEntity.java | 3 + .../entities/ApplicationEntity.java | 3 + .../entities/CommunicationEntity.java | 5 + .../enums/CommunicationInitiatorTypeEnum.java | 18 +++ .../enums/DocumentSourceTypeEnum.java | 3 +- .../enums/UserActionContextEnum.java | 3 +- ...ionTechnicalEvaluationRejectedRequest.java | 13 ++ .../request/AppointmentCreationRequest.java | 2 + .../request/CreateAppointmentRequest.java | 3 + .../ApplicationAmendmentRequestResponse.java | 1 + .../response/CommunicationResponseBean.java | 3 + .../repositories/CommunicationRepository.java | 2 + .../ApplicationAmendmentRequestService.java | 3 +- .../service/ApplicationEvaluationService.java | 6 +- .../service/CommunicationService.java | 5 +- ...pplicationAmendmentRequestServiceImpl.java | 12 +- .../ApplicationEvaluationServiceImpl.java | 5 + .../impl/CommunicationServiceImpl.java | 6 +- .../impl/S3ReUploadMigrationService.java | 18 ++- .../UserSignedAndDelegationServiceImpl.java | 2 +- .../gepafin/tendermanagement/util/Utils.java | 16 ++ .../api/ApplicationAmendmentRequestApi.java | 15 +- .../rest/api/ApplicationEvaluationApi.java | 18 ++- .../web/rest/api/CommunicationApi.java | 17 +- ...ApplicationAmendmentRequestController.java | 18 ++- .../ApplicationEvaluationApiController.java | 11 ++ .../api/impl/CommunicationController.java | 9 +- .../db/changelog/db.changelog-1.0.0.xml | 34 ++++ src/main/resources/message_en.properties | 3 + src/main/resources/message_it.properties | 3 +- 42 files changed, 561 insertions(+), 150 deletions(-) create mode 100644 src/main/java/net/gepafin/tendermanagement/enums/CommunicationInitiatorTypeEnum.java create mode 100644 src/main/java/net/gepafin/tendermanagement/model/request/ApplicationTechnicalEvaluationRejectedRequest.java diff --git a/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java b/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java index b6b5f637..371437a6 100644 --- a/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java +++ b/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java @@ -1,5 +1,8 @@ package net.gepafin.tendermanagement.constants; +import java.util.Arrays; +import java.util.List; + public class GepafinConstant { public static final String USER_CREATED_SUCCESS_MSG = "user.created.success"; @@ -615,6 +618,11 @@ public class GepafinConstant { " \n" + " \n" + ""; + public static final String UPDATE_APPLICATION_TECHNICAL_EVALUATION_REJECTED_MSG = "application.technical.evaluation.rejected.success"; + public static final String SUBJECT = "subject"; + public static final List MANUAL_EMAIL_KEYS = Arrays.asList(SUBJECT, MESSAGE); + public static final String INVALID_EMAIL_JSON = "invalid.email.json"; + } diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java index 57222c69..b7ff4e78 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java @@ -34,6 +34,7 @@ import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.jpa.domain.Specification; import org.springframework.stereotype.Component; +import org.springframework.web.multipart.MultipartFile; import java.math.BigDecimal; import java.time.LocalDateTime; @@ -149,6 +150,9 @@ public class ApplicationAmendmentRequestDao { @Autowired private EmailDao emailDao; + @Autowired + private DocumentDao documentDao; + public ApplicationAmendmentRequestResponse getApplicationDataForAmendment(Long applicationEvaluationId) { log.info("Fetching the application data for the Amendment process {}", applicationEvaluationId); ApplicationEvaluationEntity applicationEvaluationEntity = applicationEvaluationService.validateApplicationEvaluation(applicationEvaluationId); @@ -302,10 +306,10 @@ public class ApplicationAmendmentRequestDao { return filteredList; } - public ApplicationAmendmentRequestResponse createApplicationAmendmentRequest(Long applicationEvaluationId, ApplicationAmendmentRequest applicationAmendmentRequest) { + public ApplicationAmendmentRequestResponse createApplicationAmendmentRequest(Long applicationEvaluationId, List files, ApplicationAmendmentRequest applicationAmendmentRequest,Long userId) { log.info("Submiting application data for amendment Process with details: {}", applicationEvaluationId); - ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity = createApplicationAmendmentRequestEntity(applicationAmendmentRequest, applicationEvaluationId); + ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity = createApplicationAmendmentRequestEntity(applicationAmendmentRequest, applicationEvaluationId,files, userId); ApplicationAmendmentRequestResponse applicationAmendmentRequestResponse = convertEntityToResponse(applicationAmendmentRequestEntity,false); log.info("Application submitted successfully for amendment", applicationAmendmentRequestResponse); if (Boolean.TRUE.equals(applicationAmendmentRequestResponse.getIsSendEmail())) { @@ -323,7 +327,7 @@ public class ApplicationAmendmentRequestDao { return applicationAmendmentRequestResponse; } - public ApplicationAmendmentRequestEntity createApplicationAmendmentRequestEntity(ApplicationAmendmentRequest applicationAmendmentRequest,Long applicationEvaluationId) { + public ApplicationAmendmentRequestEntity createApplicationAmendmentRequestEntity(ApplicationAmendmentRequest applicationAmendmentRequest,Long applicationEvaluationId,List files,Long userId) { ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity = new ApplicationAmendmentRequestEntity(); applicationAmendmentRequestEntity.setNote(applicationAmendmentRequest.getNote()); applicationAmendmentRequestEntity.setResponseDays(applicationAmendmentRequest.getResponseDays()); @@ -383,7 +387,15 @@ public class ApplicationAmendmentRequestDao { applicationAmendmentRequestEntity.setProtocol(protocolEntity); ApplicationAmendmentRequestEntity applicationAmendment = saveApplicationAmendmentRequestEntity(applicationAmendmentRequestEntity, null, VersionActionTypeEnum.INSERT); log.info("Amendment request saved with ID={}", applicationAmendment.getId()); - + List documentResponseBeans= uploadInitialDocument(userId,files,applicationAmendment); + List initialDocumentIds = documentResponseBeans.stream() + .map(DocumentResponseBean::getId) + .collect(Collectors.toList()); + String initialDocumentId = initialDocumentIds.stream() + .map(String::valueOf) + .collect(Collectors.joining(",")); + applicationAmendment.setAmendmentInitialDocument(initialDocumentId); + applicationAmendment = saveApplicationAmendmentRequestEntity(applicationAmendment, null, VersionActionTypeEnum.UPDATE); String evaluationStatusType = applicationEvaluationEntity.getStatus(); if (Boolean.FALSE.equals(evaluationStatusType.equals((ApplicationEvaluationStatusTypeEnum.SOCCORSO.getValue())))){ // applicationEvaluationEntity.setStatus(ApplicationEvaluationStatusTypeEnum.SOCCORSO.getValue()); @@ -468,45 +480,65 @@ public class ApplicationAmendmentRequestDao { // List amendmentDetailsList = // Utils.convertJsonStringToList(applicationAmendmentRequestEntity.getAmendmentDocument(), // AmendmentDetailsResponseBean.class); - AmendmentDetailsResponseBean amendmentDetails = Utils.convertStringToObject(applicationAmendmentRequestEntity.getAmendmentDocument() ,AmendmentDetailsResponseBean.class); - if(amendmentDetails!=null) { - List documentResponseBeans = new ArrayList<>(); - if (amendmentDetails.getAmendmentDocuments() != null) { - // Extract the comma-separated document IDs as a string - String documentIdsString = amendmentDetails.getAmendmentDocuments(); + AmendmentDetailsResponseBean amendmentDetails = Utils.convertStringToObject(applicationAmendmentRequestEntity.getAmendmentDocument(), AmendmentDetailsResponseBean.class); + if (amendmentDetails != null) { + List documentResponseBeans = new ArrayList<>(); + if (amendmentDetails.getAmendmentDocuments() != null) { + // Extract the comma-separated document IDs as a string + String documentIdsString = amendmentDetails.getAmendmentDocuments(); - if (documentIdsString != null && !documentIdsString.trim().isEmpty()) { - // Split the comma-separated values and process them - List documentIds = Arrays.stream(documentIdsString.split(",")) - .map(String::trim) - .filter(id -> !id.isEmpty()) - .collect(Collectors.toList()); + if (documentIdsString != null && !documentIdsString.trim().isEmpty()) { + // Split the comma-separated values and process them + List documentIds = Arrays.stream(documentIdsString.split(",")) + .map(String::trim) + .filter(id -> !id.isEmpty()) + .collect(Collectors.toList()); - documentResponseBeans.addAll( - documentIds.stream() - .map(id -> { - try { - return createDocumentResponseBean(id); // Convert to Long - } catch (NumberFormatException e) { - // Handle invalid document IDs gracefully - return null; - } - }) - .filter(Objects::nonNull) // Skip null responses - .collect(Collectors.toList()) - ); - response.setAmendmentNotes(amendmentDetails.getAmendmentNotes()); - response.setValid(amendmentDetails.getValid()); - } + documentResponseBeans.addAll( + documentIds.stream() + .map(id -> { + try { + return createDocumentResponseBean(id); // Convert to Long + } catch (NumberFormatException e) { + // Handle invalid document IDs gracefully + return null; + } + }) + .filter(Objects::nonNull) // Skip null responses + .collect(Collectors.toList()) + ); + response.setAmendmentNotes(amendmentDetails.getAmendmentNotes()); + response.setValid(amendmentDetails.getValid()); } - response.setAmendmentDocuments(documentResponseBeans); } - - - + response.setAmendmentDocuments(documentResponseBeans); + } } + List initialDocumentBeans = new ArrayList<>(); + String initialDocuments = applicationAmendmentRequestEntity.getAmendmentInitialDocument(); + if (initialDocuments != null && !initialDocuments.trim().isEmpty()) { + // Split the comma-separated values and process them + List documentIds = Arrays.stream(initialDocuments.split(",")) + .map(String::trim) + .filter(id -> !id.isEmpty()) + .collect(Collectors.toList()); + initialDocumentBeans.addAll( + documentIds.stream() + .map(id -> { + try { + return createDocumentResponseBean(id); // Convert to Long + } catch (NumberFormatException e) { + // Handle invalid document IDs gracefully + return null; + } + }) + .filter(Objects::nonNull) // Skip null responses + .collect(Collectors.toList()) + ); + } + response.setAmendmentInitialDocuments(initialDocumentBeans); processFormFields(amendmentFormFields, fieldIdToLabelMap, formFieldEntityMap, response); return response; @@ -599,23 +631,7 @@ public class ApplicationAmendmentRequestDao { 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(); + List documentResponseBeans = getDocumentResponseBean(amendmentFormField.getFieldValue()); // Map to application form field response bean ApplicationFormFieldEntity formFieldEntity = formFieldEntityMap.get(amendmentFormField.getFieldId()); @@ -634,6 +650,27 @@ public class ApplicationAmendmentRequestDao { response.setApplicationFormFields(fileDetails); } + private List getDocumentResponseBean(String documentId) { + List documentIds = extractIds(documentId); + 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(); + return documentResponseBeans; + } + private String buildBeneficiaryName(UserEntity userEntity) { if (userEntity.getBeneficiary() == null) { return ""; @@ -1868,5 +1905,10 @@ public class ApplicationAmendmentRequestDao { log.info("Application submitted successfully for amendment", applicationAmendmentRequestResponse); return applicationAmendmentRequestResponse; } - + public List uploadInitialDocument(Long userId,List files,ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity){ + if(files!=null) { + return documentDao.uploadFiles(userId, files, applicationAmendmentRequestEntity.getId(), DocumentSourceTypeEnum.AMENDMENT, DocumentTypeEnum.DOCUMENT); + } + return new ArrayList<>(); + } } diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java index 02963812..35cd54a5 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java @@ -1,5 +1,6 @@ package net.gepafin.tendermanagement.dao; +import com.amazonaws.services.dynamodbv2.xspec.L; import com.amazonaws.services.dynamodbv2.xspec.S; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.JsonNode; @@ -131,6 +132,9 @@ public class ApplicationDao { @Autowired private AssignedApplicationsRepository assignedApplicationsRepository; + @Autowired + private CommunicationRepository communicationRepository; + // @Value("${default_System_Receiver_Email}") // private String defaultSystemReceiverEmail; @@ -1372,7 +1376,7 @@ public class ApplicationDao { ApplicationSignedDocumentEntity oldApplicationSignedDocument = Utils.getClonedEntityForData(applicationSignedDocumentEntity); String oldS3Path = applicationSignedDocumentEntity.getFilePath(); log.debug("Old S3 path: {} ", oldS3Path); - String newS3Path = s3ConfigBean.generateDocumentPathForOther(DocOtherSourceTypeEnum.DELETED_USER_SIGNED_DOCUMENT,applicationSignedDocumentEntity.getApplication().getCall().getId(),applicationSignedDocumentEntity.getApplication().getId(),0L); + String newS3Path = s3ConfigBean.generateDocumentPathForOther(DocOtherSourceTypeEnum.DELETED_USER_SIGNED_DOCUMENT,applicationSignedDocumentEntity.getApplication().getCall().getId(),applicationSignedDocumentEntity.getApplication().getId(),0L,0L); log.debug("Generated new S3 path for deleted document: {}", newS3Path); UploadFileOnAmazonS3Response response = amazonS3Service.moveFile(applicationSignedDocumentEntity.getFileName(), oldS3Path, newS3Path); @@ -1407,7 +1411,7 @@ public class ApplicationDao { } private String generateS3PathForDelegation(Long callId, Long applicationId) { try { - return s3ConfigBean.generateDocumentPathForOther(DocOtherSourceTypeEnum.USER_SIGNED_DOCUMENT, callId, applicationId,0L); + return s3ConfigBean.generateDocumentPathForOther(DocOtherSourceTypeEnum.USER_SIGNED_DOCUMENT, callId, applicationId,0L,0L); } catch (IllegalArgumentException e) { log.error("Failed to generate S3 path for delegation | callId: {}, applicationId: {}, error: {}", callId, applicationId, e.getMessage(), e); throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.S3_PATH_GENERATION_ERROR_MSG)); @@ -1529,11 +1533,12 @@ public class ApplicationDao { ApplicationSignedDocumentStatusEnum.ACTIVE.getValue()); List amendmentDocuments = fetchAmendmentDocuments(applicationId); List evaluationDocuments = fetchEvaluationDocuments(applicationId); + List communicationnDocuments = fetchCommunicationDocuments(applicationId); if (documents.isEmpty() && signedDocument == null && amendmentDocuments.isEmpty() && evaluationDocuments.isEmpty()) { log.warn("No documents found for applicationId: {}", applicationId); throw new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.DOCUMENT_NOT_FOUND)); } - return createZipWithDocuments(applicationEntity, documents, signedDocument, amendmentDocuments, evaluationDocuments, applicationId); + return createZipWithDocuments(applicationEntity, documents, signedDocument, amendmentDocuments, evaluationDocuments, applicationId,communicationnDocuments); } private void validateAssignedUser(HttpServletRequest request, Long applicationId) { @@ -1582,6 +1587,28 @@ public class ApplicationDao { } return Collections.emptyList(); } + private List fetchCommunicationDocuments(Long applicationId) { + log.info("Fetching communication documents for applicationId: {}", applicationId); + List amendmentRequests = applicationAmendmentRequestRepository.findByApplicationIdAndIsDeletedFalse(applicationId); + List amendmentRequestIds = amendmentRequests.stream() + .map(ApplicationAmendmentRequestEntity::getId) + .collect(Collectors.toList()); + List communicationEntities=communicationRepository.findByApplicationAmendmentRequestIdInAndIsDeletedFalse(amendmentRequestIds); + List documentEntities=new ArrayList<>(); + if (Boolean.FALSE.equals(communicationEntities.isEmpty())) { + for (CommunicationEntity communicationEntity : communicationEntities) { + { + Long communicationId = communicationEntity.getId(); + log.debug("Found communication entity with id: {}", communicationId); + + List communicationDocuments= documentRepository.findBySourceIdInAndSourceAndIsDeletedFalse(Collections.singleton(communicationId), DocumentSourceTypeEnum.COMMUNICATION.getValue()); + documentEntities.addAll(communicationDocuments); + } + } + return documentEntities; + } + return Collections.emptyList(); + } private String fetchProtocolNumberForAmendment(Long amendmentRequestId) { ApplicationAmendmentRequestEntity amendmentRequest = applicationAmendmentRequestRepository.findByIdAndIsDeletedFalse(amendmentRequestId).orElse(null); @@ -1603,12 +1630,12 @@ public class ApplicationDao { } } private byte[] createZipWithDocuments(ApplicationEntity applicationEntity, List documents, ApplicationSignedDocumentEntity signedDocument, - List amendmentDocuments, List evaluationDocuments, Long applicationId) { + List amendmentDocuments, List evaluationDocuments, Long applicationId,List communicationDocuments) { try (ByteArrayOutputStream zipOutputStream = new ByteArrayOutputStream(); ZipOutputStream zos = new ZipOutputStream(zipOutputStream)) { Long callId = applicationEntity.getCall().getId(); // Add Application Documents - String appS3Folder = s3PathConfig.generateDocumentPath(DocumentSourceTypeEnum.APPLICATION, callId, applicationId, 0L); + String appS3Folder = s3PathConfig.generateDocumentPath(DocumentSourceTypeEnum.APPLICATION, callId, applicationId, 0L,0L); for (DocumentEntity document : documents) { String fileName = Utils.extractFileName(document.getFilePath()); addDocumentToZip(zos, appS3Folder, document.getFilePath(), fileName); @@ -1616,7 +1643,7 @@ public class ApplicationDao { // Add Signed Document if (signedDocument != null) { String signedFolder = "SIGNED_DOCUMENT/"; - String signedDocS3Folder = s3PathConfig.generateDocumentPathForOther(DocOtherSourceTypeEnum.USER_SIGNED_DOCUMENT, callId, applicationId, 0L); + String signedDocS3Folder = s3PathConfig.generateDocumentPathForOther(DocOtherSourceTypeEnum.USER_SIGNED_DOCUMENT, callId, applicationId, 0L,0L); String fileName = signedDocument.getFileName(); addDocumentToZip(zos, signedDocS3Folder, signedDocument.getFilePath(), signedFolder + fileName); } @@ -1624,17 +1651,24 @@ public class ApplicationDao { for (DocumentEntity amendmentDocument : amendmentDocuments) { String protocolNumber = fetchProtocolNumberForAmendment(amendmentDocument.getSourceId()); String amendmentFolder = "SOCCORSO_" + protocolNumber + "/"; - String amendmentS3Folder = s3PathConfig.generateDocumentPath(DocumentSourceTypeEnum.AMENDMENT, callId, applicationId, amendmentDocument.getSourceId()); + String amendmentS3Folder = s3PathConfig.generateDocumentPath(DocumentSourceTypeEnum.AMENDMENT, callId, applicationId, amendmentDocument.getSourceId(),0L); String fileName = Utils.extractFileName(amendmentDocument.getFilePath()); addDocumentToZip(zos, amendmentS3Folder, amendmentDocument.getFilePath(), amendmentFolder + fileName); } // Add Evaluation Documents for (DocumentEntity evaluationDocument : evaluationDocuments) { String evaluationFolder = "EVALUATION/"; - String evaluationS3Folder = s3PathConfig.generateDocumentPath(DocumentSourceTypeEnum.EVALUATION, callId, applicationId, evaluationDocument.getSourceId()); + String evaluationS3Folder = s3PathConfig.generateDocumentPath(DocumentSourceTypeEnum.EVALUATION, callId, applicationId, evaluationDocument.getSourceId(),0L); String fileName = Utils.extractFileName(evaluationDocument.getFilePath()); addDocumentToZip(zos, evaluationS3Folder, evaluationDocument.getFilePath(), evaluationFolder + fileName); } + for (DocumentEntity communicationDocument : communicationDocuments) { + Optional communicationEntity=communicationRepository.findByIdAndIsDeletedFalse(communicationDocument.getSourceId()); + String evaluationFolder = "COMMUNICATION/"; + String evaluationS3Folder = s3PathConfig.generateDocumentPath(DocumentSourceTypeEnum.COMMUNICATION, callId, applicationId, communicationEntity.get().getApplicationAmendmentRequest().getId(),communicationDocument.getSourceId()); + String fileName = Utils.extractFileName(communicationDocument.getFilePath()); + addDocumentToZip(zos, evaluationS3Folder, communicationDocument.getFilePath(), evaluationFolder + fileName); + } zos.finish(); return zipOutputStream.toByteArray(); } catch (IOException e) { diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java index cf135a24..fbbd5a50 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java @@ -1942,17 +1942,17 @@ public class ApplicationEvaluationDao { log.info("Application status updated to {} for applicationId: {}", newStatus, application.getId()); } - if(newStatus.equals(ApplicationStatusForEvaluation.TECHNICAL_EVALUATION_REJECTED)) { - application.setStatus(newStatus.getValue()); - log.info("Application status updated to {} for applicationId: {}", newStatus, application.getId()); - emailNotificationDao.sendMailForApplicationTechnicalEvaluationRejected(application,hub,existingEntity); - application.setDateRejected(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); - emailSendResponse = emailDao.buildEmailSendResponseFromRequest(request); - responses = List.of(emailSendResponse); - if (!Boolean.TRUE.equals(emailSendResponse.getIsEmailSend())) { - saveEmailSendResponseToEvaluation(emailSendResponse, existingEntity); - } - } +// if(newStatus.equals(ApplicationStatusForEvaluation.TECHNICAL_EVALUATION_REJECTED)) { +// application.setStatus(newStatus.getValue()); +// log.info("Application status updated to {} for applicationId: {}", newStatus, application.getId()); +// emailNotificationDao.sendMailForApplicationTechnicalEvaluationRejected(application,hub,existingEntity); +// application.setDateRejected(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); +// emailSendResponse = emailDao.buildEmailSendResponseFromRequest(request); +// responses = List.of(emailSendResponse); +// if (!Boolean.TRUE.equals(emailSendResponse.getIsEmailSend())) { +// saveEmailSendResponseToEvaluation(emailSendResponse, existingEntity); +// } +// } application = applicationRepository.save(application); ApplicationEvaluationEntity oldApplicationEvaluation = Utils.getClonedEntityForData(existingEntity); @@ -2605,6 +2605,43 @@ public class ApplicationEvaluationDao { return BigDecimal.ZERO; } } + public ApplicationEvaluationResponse updateApplicationToTechnicalEvaluationRejected(ApplicationTechnicalEvaluationRejectedRequest applicationRequest, Long assignedApplicationsId) { + Optional existingEntityOptional = + applicationEvaluationRepository.findByAssignedApplicationsEntity_IdAndIsDeletedFalse(assignedApplicationsId); + Utils.validateEmailJson(applicationRequest.getEmailJson()); + Optional assignedApplications = + assignedApplicationsRepository.findByIdAndIsDeletedFalse(assignedApplicationsId); + ApplicationEntity application = applicationService.validateApplication(assignedApplications.get().getApplication().getId()); + UserEntity user=userService.validateUser(application.getUserId()); + HubEntity hub=user.getHub(); + EmailSendResponse emailSendResponse = new EmailSendResponse(); + if (existingEntityOptional.isPresent()) { + ApplicationEvaluationEntity existingEntity = existingEntityOptional.get(); + ApplicationEntity oldApplicationEntity = Utils.getClonedEntityForData(application); + List responses = new ArrayList<>(); + + application.setStatus(ApplicationStatusForEvaluation.TECHNICAL_EVALUATION_REJECTED.getValue()); + log.info("Application status updated to {} for applicationId: {}", ApplicationStatusForEvaluation.TECHNICAL_EVALUATION_REJECTED, application.getId()); + emailNotificationDao.sendMailForApplicationTechnicalEvaluationRejected(application, hub, existingEntity,applicationRequest.getEmailJson()); + application.setDateRejected(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); + application.setEmailJson(Utils.convertMapIntoJsonString(applicationRequest.getEmailJson())); + emailSendResponse = emailDao.buildEmailSendResponseFromRequest(request); + responses = List.of(emailSendResponse); + if (!Boolean.TRUE.equals(emailSendResponse.getIsEmailSend())) { + saveEmailSendResponseToEvaluation(emailSendResponse, existingEntity); + } + application = applicationRepository.save(application); + + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplicationEntity).newData(application).build()); + + ApplicationEvaluationResponse response = convertToResponse(existingEntity); + if (!Boolean.TRUE.equals(emailSendResponse.getIsEmailSend())) { + response.setEmailSendResponse(responses); + } + return response; + } + return null; + } } diff --git a/src/main/java/net/gepafin/tendermanagement/dao/AppointmentDao.java b/src/main/java/net/gepafin/tendermanagement/dao/AppointmentDao.java index fa7b9ae8..fcccd5e6 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/AppointmentDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/AppointmentDao.java @@ -1144,6 +1144,7 @@ public class AppointmentDao { richiestaCliente.setNota(requestNota); richiestaCliente.setDurataMesiFinanziamento(createAppointmentRequest.getDurataMesiFinanziamento()); richiestaCliente.setImportoBreveTermine(createAppointmentRequest.getImportoBreveTermine()); + richiestaCliente.setDataAppuntamento(createAppointmentRequest.getDataAppuntamento()); richiestaClienteList.add(richiestaCliente); } diff --git a/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java b/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java index d0bef93e..0f688aaf 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java @@ -155,7 +155,7 @@ public class CallDao { for (DocumentEntity document : documents) { log.info("Adding document to ZIP: documentId={}, fileName={}", document.getId(), document.getFileName()); - String s3Folder = s3PathConfig.generateDocumentPath(DocumentSourceTypeEnum.CALL, callId, 0L,0L); + String s3Folder = s3PathConfig.generateDocumentPath(DocumentSourceTypeEnum.CALL, callId, 0L,0L,0L); try (InputStream fileInputStream = amazonS3Service.getFile(s3Folder, document.getFilePath())) { String fileName = Utils.extractFileName(document.getFilePath()); ZipEntry zipEntry = new ZipEntry(fileName); diff --git a/src/main/java/net/gepafin/tendermanagement/dao/CommunicationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/CommunicationDao.java index c41aee3f..686ac828 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/CommunicationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/CommunicationDao.java @@ -5,13 +5,19 @@ import net.gepafin.tendermanagement.config.Translator; import net.gepafin.tendermanagement.constants.GepafinConstant; import net.gepafin.tendermanagement.entities.ApplicationAmendmentRequestEntity; import net.gepafin.tendermanagement.entities.CommunicationEntity; +import net.gepafin.tendermanagement.entities.DocumentEntity; +import net.gepafin.tendermanagement.enums.CommunicationInitiatorTypeEnum; +import net.gepafin.tendermanagement.enums.DocumentSourceTypeEnum; +import net.gepafin.tendermanagement.enums.DocumentTypeEnum; import net.gepafin.tendermanagement.enums.VersionActionTypeEnum; import net.gepafin.tendermanagement.model.request.CommunicationRequestBean; import net.gepafin.tendermanagement.model.request.VersionHistoryRequest; import net.gepafin.tendermanagement.model.response.ApplicationAmendmentResponse; import net.gepafin.tendermanagement.model.response.CommunicationResponseBean; +import net.gepafin.tendermanagement.model.response.DocumentResponseBean; import net.gepafin.tendermanagement.repositories.CommunicationRepository; import net.gepafin.tendermanagement.service.ApplicationAmendmentRequestService; +import net.gepafin.tendermanagement.service.DocumentService; import net.gepafin.tendermanagement.util.LoggingUtil; import net.gepafin.tendermanagement.util.Utils; import net.gepafin.tendermanagement.util.Validator; @@ -22,9 +28,12 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import org.springframework.web.multipart.MultipartFile; import java.time.LocalDateTime; +import java.util.ArrayList; import java.util.List; +import java.util.stream.Collectors; @Component public class CommunicationDao { @@ -45,17 +54,48 @@ public class CommunicationDao { @Autowired private HttpServletRequest request; - public CommunicationResponseBean addCommentToAmendmentRequest(HttpServletRequest request, CommunicationRequestBean communicationReq, Long amendmentId) { + @Autowired + private DocumentDao documentDao; + + @Autowired + private ApplicationAmendmentRequestDao applicationAmendmentRequestDao; + + @Autowired + private DocumentService documentService; + + public CommunicationResponseBean addCommentToAmendmentRequest(HttpServletRequest request, CommunicationRequestBean communicationReq, Long amendmentId, List files) { log.info("Adding communication request..."); - CommunicationEntity communicationEntity = convertToCommunicationCommentEntity(communicationReq, amendmentId); - communicationEntity = communicationRepository.save(communicationEntity); + List communicationDocumentBeans = new ArrayList<>(); + CommunicationEntity communicationEntity = convertToCommunicationCommentEntity(communicationReq, amendmentId,communicationDocumentBeans,files); /** This code is responsible for adding a version history log for the "adding comment to amendment request" operation. **/ loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.INSERT).oldData(null).newData(communicationEntity).build()); log.info("Added comment: {}", communicationEntity); - return convertToCommunicationResponseBean(communicationEntity); + communicationDocumentBeans=getDocumentResponseBean(communicationEntity); + return convertToCommunicationResponseBean(communicationEntity,communicationDocumentBeans); + } + + private List getDocumentResponseBean(CommunicationEntity communicationEntity) { + List documentIds = applicationAmendmentRequestDao.extractIds(communicationEntity.getDocuments()); + 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(); + return documentResponseBeans; } public String deleteComment(Long amendmentId, Long commentId) { @@ -90,6 +130,7 @@ public class CommunicationDao { public CommunicationResponseBean updateAmendmentComment(CommunicationRequestBean communicationRequestBean, Long amendmentId, Long commentId) { log.info("Updating communication comment..."); + CommunicationEntity existingComment = communicationRepository.findById(commentId) .orElseThrow(() -> new CustomValidationException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.COMMENT_NOT_FOUND))); //cloned for old data for communication @@ -106,11 +147,11 @@ public class CommunicationDao { /** This code is responsible for adding a version history log for the "updating comment to amendment request" operation. **/ loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldCommentData).newData(existingComment).build()); - - return convertToCommunicationResponseBean(existingComment); + List communicationDocumentBeans=getDocumentResponseBean(existingComment); + return convertToCommunicationResponseBean(existingComment,communicationDocumentBeans); } - private CommunicationResponseBean convertToCommunicationResponseBean(CommunicationEntity entity) { + private CommunicationResponseBean convertToCommunicationResponseBean(CommunicationEntity entity,List communicationResponseBean) { CommunicationResponseBean response = new CommunicationResponseBean(); response.setComment(entity.getCommunicationComment()); @@ -122,10 +163,11 @@ public class CommunicationDao { response.setSenderUserId(entity.getSenderUserId()); response.setReceiverUserId(entity.getReceiverUserId()); response.setId(entity.getId()); + response.setDocuments(communicationResponseBean); return response; } - private CommunicationEntity convertToCommunicationCommentEntity(CommunicationRequestBean communicationReq, Long amendmentId) { + private CommunicationEntity convertToCommunicationCommentEntity(CommunicationRequestBean communicationReq, Long amendmentId,List communicationDocumentBean,List files) { ApplicationAmendmentRequestEntity amendmentRequest = applicationAmendmentRequestService.validateApplicationAmendmentRequest(amendmentId); @@ -136,12 +178,24 @@ public class CommunicationDao { communicationEntity.setIsDeleted(false); communicationEntity.setCommentedDate(LocalDateTime.now()); if(validator.checkIsPreInstructor()){ + communicationEntity.setIntiatorType(CommunicationInitiatorTypeEnum.INSTRUCTOR.getValue()); communicationEntity.setSenderUserId(amendmentRequest.getApplicationEvaluationEntity().getUserId()); communicationEntity.setReceiverUserId(amendmentRequest.getApplicationEvaluationEntity().getAssignedApplicationsEntity().getApplication().getUserId()); } else if(Boolean.TRUE.equals(validator.checkIsBeneficiary()) || Boolean.TRUE.equals(validator.checkIsConfidi())) { + communicationEntity.setIntiatorType(CommunicationInitiatorTypeEnum.BENEFICIARY.getValue()); communicationEntity.setSenderUserId(amendmentRequest.getApplicationEvaluationEntity().getAssignedApplicationsEntity().getApplication().getUserId()); communicationEntity.setReceiverUserId(amendmentRequest.getApplicationEvaluationEntity().getUserId()); } + communicationEntity = communicationRepository.save(communicationEntity); + communicationDocumentBean=documentDao.uploadFiles(communicationEntity.getSenderUserId(),files,communicationEntity.getId(), DocumentSourceTypeEnum.COMMUNICATION, DocumentTypeEnum.DOCUMENT); + List communicationDocumentIds = communicationDocumentBean.stream() + .map(DocumentResponseBean::getId) + .collect(Collectors.toList()); + String communicationDocumentId = communicationDocumentIds.stream() + .map(String::valueOf) + .collect(Collectors.joining(",")); + communicationEntity.setDocuments(communicationDocumentId); + communicationEntity = communicationRepository.save(communicationEntity); return communicationEntity; } } diff --git a/src/main/java/net/gepafin/tendermanagement/dao/CompanyDocumentDao.java b/src/main/java/net/gepafin/tendermanagement/dao/CompanyDocumentDao.java index acf12515..5c5fa136 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/CompanyDocumentDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/CompanyDocumentDao.java @@ -282,7 +282,7 @@ public class CompanyDocumentDao { validator.validateUserWithCompany(request,companyDocumentEntity.getCompanyId()); String companyDocumentPath = companyDocumentEntity.getFilePath(); - String documentPath = s3ConfigBean.generateDocumentPath(DocumentSourceTypeEnum.APPLICATION,applicationEntity.getCall().getId(),applicationId,0L); + String documentPath = s3ConfigBean.generateDocumentPath(DocumentSourceTypeEnum.APPLICATION,applicationEntity.getCall().getId(),applicationId,0L,0L); log.info("Original Paths - oldPath: {}, newPath: {}", companyDocumentPath, documentPath); diff --git a/src/main/java/net/gepafin/tendermanagement/dao/DelegationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/DelegationDao.java index b39efce7..6af7e820 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/DelegationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/DelegationDao.java @@ -92,7 +92,7 @@ public class DelegationDao { public ByteArrayOutputStream generateDocument(Map placeholders, String templateName) { try { - String s3Folder = s3ConfigBean.generateDocumentPathForOther(DocOtherSourceTypeEnum.TEMPLATE, 0L, 0L,0L); + String s3Folder = s3ConfigBean.generateDocumentPathForOther(DocOtherSourceTypeEnum.TEMPLATE, 0L, 0L,0L,0L); InputStream templateStream = amazonS3Service.getFile(s3Folder ,templateName); XWPFDocument doc = loadTemplate(templateStream); replacePlaceholders(doc, placeholders); diff --git a/src/main/java/net/gepafin/tendermanagement/dao/DocumentDao.java b/src/main/java/net/gepafin/tendermanagement/dao/DocumentDao.java index 013bf9e5..4f87d2bc 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/DocumentDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/DocumentDao.java @@ -89,6 +89,9 @@ public class DocumentDao { @Autowired private ApplicationEvaluationDao applicationEvaluationDao; + @Autowired + private CommunicationRepository communicationRepository; + // @Value("${aws.s3.url.folder}") // private String s3Folder; @@ -164,6 +167,7 @@ public class DocumentDao { Long applicationId = 0L; Long amendmentId = 0L; Long evaluationId = 0L; + Long communicationId = 0L; Long callId = sourceId; if (type == DocumentSourceTypeEnum.APPLICATION) { applicationId = sourceId; @@ -181,9 +185,17 @@ public class DocumentDao { applicationId = applicationEntity.getId(); callId = applicationEntity.getCall().getId(); log.info("Processing document of type EVALUATION .Resolved evaluationId={}, applicationId={}, callId={}", evaluationId, applicationId, callId); + }else if (type == DocumentSourceTypeEnum.COMMUNICATION) { + communicationId = sourceId; + Optional communicationEntity=communicationRepository.findByIdAndIsDeletedFalse(communicationId); + Optional applicationAmendmentRequestEntity=applicationAmendmentRequestRepository.findByIdAndIsDeletedFalse(communicationEntity.get().getApplicationAmendmentRequest().getId()); + amendmentId=applicationAmendmentRequestEntity.get().getId(); + applicationId=applicationAmendmentRequestEntity.get().getApplicationId(); + callId = applicationAmendmentRequestEntity.get().getApplicationEvaluationEntity().getAssignedApplicationsEntity().getApplication().getCall().getId(); + log.info("Processing document of type COMMUNICATION .Resolved evaluationId={}, applicationId={}, callId={}", evaluationId, applicationId, callId); } try { - String s3Path = generateS3Path(type, callId, applicationId, amendmentId); + String s3Path = generateS3Path(type, callId, applicationId, amendmentId,communicationId); log.info("Generated S3 path {}", s3Path); return amazonS3Service.uploadFileOnAmazonS3(s3Path, file); } catch (Exception e) { @@ -194,9 +206,9 @@ public class DocumentDao { } - public String generateS3Path(DocumentSourceTypeEnum typeOfDocument, Long callId, Long applicationId, Long amendmentId) { + public String generateS3Path(DocumentSourceTypeEnum typeOfDocument, Long callId, Long applicationId, Long amendmentId,Long communicationId) { try { - return s3ConfigBean.generateDocumentPath(typeOfDocument, callId, applicationId, amendmentId); + return s3ConfigBean.generateDocumentPath(typeOfDocument, callId, applicationId, amendmentId,communicationId); } catch (IllegalArgumentException e) { throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.S3_PATH_GENERATION_ERROR_MSG)); } @@ -228,6 +240,7 @@ public class DocumentDao { Long applicationId = null; Long amendmentId = null; Long evaluationId = null; + Long communicationId=null; if (DocumentSourceTypeEnum.CALL.getValue().equalsIgnoreCase(documentEntity.getSource())) { callId = documentEntity.getSourceId(); @@ -305,7 +318,7 @@ public class DocumentDao { callId = applicationEntity.getCall().getId(); log.info("Processing document of type EVALUATION. Resolved evaluationId={}, applicationId={}, callId={}", evaluationId, applicationId, callId); } - deleteFileFromS3(documentEntity, callId, applicationId,amendmentId); + deleteFileFromS3(documentEntity, callId, applicationId,amendmentId,communicationId); log.info("Successfully deleted file from S3 for documentId={}", documentId); } @@ -349,6 +362,7 @@ public class DocumentDao { Long applicationId=null; Long amendmentId=null; Long evaluationId=null; + Long communicationId=null; if (type.equals(DocumentSourceTypeEnum.APPLICATION)) { callId = applicationRepository.findCallIdById(id); applicationId = id; @@ -366,6 +380,14 @@ public class DocumentDao { applicationId = applicationEntity.getId(); callId = applicationEntity.getCall().getId(); log.info("Processing document of type EVALUATION . Resolved evaluationId={}, applicationId={}, callId={}", evaluationId, applicationId, callId); + }else if (type == DocumentSourceTypeEnum.COMMUNICATION) { + communicationId = id; + Optional communicationEntity=communicationRepository.findByIdAndIsDeletedFalse(communicationId); + Optional applicationAmendmentRequestEntity=applicationAmendmentRequestRepository.findByIdAndIsDeletedFalse(communicationEntity.get().getApplicationAmendmentRequest().getId()); + amendmentId=applicationAmendmentRequestEntity.get().getId(); + applicationId=applicationAmendmentRequestEntity.get().getApplicationId(); + callId = applicationAmendmentRequestEntity.get().getApplicationEvaluationEntity().getAssignedApplicationsEntity().getApplication().getCall().getId(); + log.info("Processing document of type EVALUATION .Resolved evaluationId={}, applicationId={}, callId={}", evaluationId, applicationId, callId); } else { @@ -373,7 +395,7 @@ public class DocumentDao { applicationId = 0L; log.info("Processing document of type CALL . Resolved callId={}", callId); } - String s3Path = generateS3Path(type, callId, applicationId,amendmentId); + String s3Path = generateS3Path(type, callId, applicationId,amendmentId,communicationId); log.info("Generated S3 path {}", s3Path); return amazonS3Service.uploadFileOnAmazonS3(s3Path, file); } catch (Exception e) { @@ -386,12 +408,12 @@ public class DocumentDao { return callDao.convertToDocumentResponseBean(documentEntity); } - public void deleteFileFromS3(DocumentEntity documentEntity, Long callId, Long applicationId,Long amendmentId) { + public void deleteFileFromS3(DocumentEntity documentEntity, Long callId, Long applicationId,Long amendmentId,Long communicationId) { try { DocumentEntity oldDocumentEntity = Utils.getClonedEntityForData(documentEntity); String oldS3Path = documentEntity.getFilePath(); - String newS3Path = s3ConfigBean.generateDocumentPathForOther(DocOtherSourceTypeEnum.valueOf("DELETED_" + documentEntity.getSource().toUpperCase()), callId, applicationId,amendmentId); + String newS3Path = s3ConfigBean.generateDocumentPathForOther(DocOtherSourceTypeEnum.valueOf("DELETED_" + documentEntity.getSource().toUpperCase()), callId, applicationId,amendmentId,communicationId); log.info("Moving file to deleted path: oldS3Path={}, newS3Path={}", oldS3Path, newS3Path); UploadFileOnAmazonS3Response response = amazonS3Service.moveFile(documentEntity.getFileName(), oldS3Path, newS3Path); documentEntity.setFileName(response.getFileName()); diff --git a/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java index b22ece00..3af44ecb 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java @@ -94,6 +94,9 @@ public class EmailNotificationDao { @Autowired private ApplicationAmendmentRequestDao applicationAmendmentRequestDao; + @Autowired + private ApplicationDao applicationDao; + public void sendEmail(ApplicationEntity applicationEntity, SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum templateType, Map bodyPlaceholders, List additionalRecipients, Long amendmentId) { @@ -131,21 +134,35 @@ public class EmailNotificationDao { Optional applicationEvaluationEntity = applicationEvaluationRepository.findByApplicationIdAndIsDeletedFalse(applicationEntity.getId()); CompanyEntity company = companyService.validateCompany(applicationEntity.getCompanyId()); - ApplicationAmendmentRequestEntity applicationAmendmentRequest=applicationAmendmentRequestDao.validateApplicationAmendmentRequest(amendmentId); + ApplicationAmendmentRequestEntity applicationAmendmentRequest =null; + if(amendmentId!=null) { + applicationAmendmentRequest = applicationAmendmentRequestDao.validateApplicationAmendmentRequest(amendmentId); + } List attachmentRequests =new ArrayList<>(); + S3DocxProcessor processor = new S3DocxProcessor(s3Client); + List urls=new ArrayList<>(); + Map replacements=new HashMap<>(); + List documentEntities=new ArrayList<>(); if(systemEmailTemplateResponse.getEmailScenario().equals(EmailScenarioTypeEnum.SPECIAL_APPLICATION_AMENDMENT_REQUESTED)) { - S3DocxProcessor processor = new S3DocxProcessor(s3Client); - List urls=new ArrayList<>(); - Map replacements = Map.of( + 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()); + documentEntities=documentRepository.findBySourceInAndIsDeletedFalse(List.of(applicationAmendmentRequest.getAmendmentDocumentType(),"MODELLO_AUTOCERTIFICAZIONE","MODELLO_PRIVACY")); + } + if(Boolean.TRUE.equals(userEntity.getHub().getUniqueUuid().equals(defaultHubUuid)) && Boolean.TRUE.equals(systemEmailTemplateResponse.getEmailScenario().equals(EmailScenarioTypeEnum.APPLICATION_AMENDMENT_REQUESTED))) { + List documentIds=applicationDao.validateDocumentIds(applicationAmendmentRequest.getAmendmentInitialDocument()); + Set setOfDocumentIds = (documentIds == null) + ? Collections.emptySet() + : new HashSet<>(documentIds); + documentEntities=documentRepository.findAllByIdInAndIsDeletedFalse(setOfDocumentIds); + } + urls = documentEntities.stream() + .map(DocumentEntity::getFilePath) // or getUrl() + .collect(Collectors.toList()); + if(Boolean.FALSE.equals(urls.isEmpty())) { Map processedFiles = null; try { processedFiles = processor.processFiles(urls, replacements); @@ -159,7 +176,6 @@ public class EmailNotificationDao { attachmentRequests.add(attachmentRequest); } } - UserWithCompanyEntity userWithCompany=companyService.getUserWithCompany(userEntity.getId(),company.getId()); String companyEmail = userWithCompany.getEmail(); String contactEmail = userWithCompany.getContactEmail(); @@ -404,7 +420,7 @@ public class EmailNotificationDao { return emailConfig; } - private EmailConfig parseEmailConfig(String configJson) { + private static EmailConfig parseEmailConfig(String configJson) { ObjectMapper objectMapper = new ObjectMapper(); try { @@ -413,11 +429,27 @@ public class EmailNotificationDao { throw new IllegalArgumentException("Failed to parse email configuration JSON", e); } } - public void sendMailForApplicationTechnicalEvaluationRejected(ApplicationEntity applicationEntity,HubEntity hub,ApplicationEvaluationEntity applicationEvaluationEntity) { + public void sendMailForApplicationTechnicalEvaluationRejected(ApplicationEntity applicationEntity,HubEntity hub,ApplicationEvaluationEntity applicationEvaluationEntity,Map emailJson) { + HubEntity hubEntity = hubService.valdateHub(applicationEntity.getHubId()); + SystemEmailTemplateResponse systemEmailTemplateResponse=new SystemEmailTemplateResponse(); + systemEmailTemplateResponse.setSubject((String) emailJson.get("subject")); + systemEmailTemplateResponse.setHtmlContent((String) emailJson.get("message")); + Map subjectPlaceholders = new HashMap<>(); + CompanyEntity company = companyService.validateCompany(applicationEntity.getCompanyId()); + subjectPlaceholders.put("{{call_name}}", applicationEntity.getCall().getName()); + subjectPlaceholders.put("{{company_name}}", company.getCompanyName()); Map bodyPlaceholders = prepareEmailPlaceholdersForTechnicalEvaluationRejected(applicationEntity,hub,applicationEvaluationEntity); - sendEmail(applicationEntity, SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum.INADMISSIBILITY_NOTIFICATION_DUE_TO_TECHNICAL_EVALUATION_FAILURE, bodyPlaceholders, null, - null); + String subject = Utils.replacePlaceholders(systemEmailTemplateResponse.getSubject(), subjectPlaceholders); + String body = Utils.replacePlaceholders(systemEmailTemplateResponse.getHtmlContent(), bodyPlaceholders); + SystemEmailTemplateResponse systemEmailTemplateResponse1=new SystemEmailTemplateResponse(); + systemEmailTemplateResponse1.setSubject(subject); + systemEmailTemplateResponse1.setHtmlContent(body); + systemEmailTemplateResponse1.setEmailScenario(EmailScenarioTypeEnum.APPLICATION_TECHNICAL_EVALUATION_REJECTED); + EmailContentResponse emailContentResponse=new EmailContentResponse(subject,body,systemEmailTemplateResponse1); + UserEntity userEntity = userService.validateUser(applicationEntity.getUserId()); + sendEmails(applicationEntity, userEntity, null,null,emailContentResponse.getSystemEmailTemplateResponse(),emailContentResponse.getSubject(),emailContentResponse.getBody()); + } public Map prepareEmailPlaceholdersForTechnicalEvaluationRejected(ApplicationEntity applicationEntity,HubEntity hub,ApplicationEvaluationEntity applicationEvaluationEntity) { Map bodyPlaceholders = new HashMap<>(); diff --git a/src/main/java/net/gepafin/tendermanagement/dao/S3PathConfig.java b/src/main/java/net/gepafin/tendermanagement/dao/S3PathConfig.java index 9b55eda1..9cbc1b26 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/S3PathConfig.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/S3PathConfig.java @@ -15,26 +15,27 @@ public class S3PathConfig { @Autowired S3ConfigRepository s3ConfigRepository; - public String generateDocumentPath(DocumentSourceTypeEnum type, Long callId, Long applicationId,Long amendmentId) { + public String generateDocumentPath(DocumentSourceTypeEnum type, Long callId, Long applicationId,Long amendmentId,Long communicationId) { S3ConfigEntity config = getDocumentPath(type); - return config.getParentFolder() + "/" + buildS3Path(config.getPath(), callId, applicationId,amendmentId); + return config.getParentFolder() + "/" + buildS3Path(config.getPath(), callId, applicationId,amendmentId,communicationId); } - public String generateDocumentPathForOther(DocOtherSourceTypeEnum type, Long callId, Long applicationId,Long amendmentId) { + public String generateDocumentPathForOther(DocOtherSourceTypeEnum type, Long callId, Long applicationId,Long amendmentId,Long communicationId) { S3ConfigEntity config = getDocumentPathForOther(type); - return config.getParentFolder() + "/" + buildS3Path(config.getPath(), callId, applicationId,amendmentId); + return config.getParentFolder() + "/" + buildS3Path(config.getPath(), callId, applicationId,amendmentId,communicationId); } public String generateDocumentPathForDelegationAndSignedDocument(DocOtherSourceTypeEnum type) { S3ConfigEntity config = getDocumentPathForOther(type); return config.getParentFolder() + "/" + config.getPath(); } - private String buildS3Path(String pathTemplate, Long callId, Long applicationId, Long amendmentId) { + private String buildS3Path(String pathTemplate, Long callId, Long applicationId, Long amendmentId,Long communicationId) { return pathTemplate .replace("{call_id}", callId != null && callId != 0L ? "call_" + callId : "") .replace("{application_id}", applicationId != null && applicationId != 0L ? "application_" + applicationId : "") - .replace("{amendment_id}", amendmentId != null && amendmentId != 0L ? "amendment_" + amendmentId : ""); + .replace("{amendment_id}", amendmentId != null && amendmentId != 0L ? "amendment_" + amendmentId : "") + .replace("{communication_id}", communicationId != null && communicationId != 0L ? "communication_" + communicationId : ""); } private S3ConfigEntity getDocumentPath(DocumentSourceTypeEnum type) { diff --git a/src/main/java/net/gepafin/tendermanagement/entities/ApplicationAmendmentRequestEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/ApplicationAmendmentRequestEntity.java index 7195e1cf..1ccd4eed 100644 --- a/src/main/java/net/gepafin/tendermanagement/entities/ApplicationAmendmentRequestEntity.java +++ b/src/main/java/net/gepafin/tendermanagement/entities/ApplicationAmendmentRequestEntity.java @@ -74,4 +74,7 @@ public class ApplicationAmendmentRequestEntity extends BaseEntity { @Column(name = "AMENDMENT_DOCUMENT_TYPE") private String amendmentDocumentType; + @Column(name = "AMENDMENT_INITIAL_DOCUMENT") + private String amendmentInitialDocument; + } diff --git a/src/main/java/net/gepafin/tendermanagement/entities/ApplicationEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/ApplicationEntity.java index dacc3541..d37477bd 100644 --- a/src/main/java/net/gepafin/tendermanagement/entities/ApplicationEntity.java +++ b/src/main/java/net/gepafin/tendermanagement/entities/ApplicationEntity.java @@ -79,4 +79,7 @@ public class ApplicationEntity extends BaseEntity { @Column(name="VAT_NUMBER") private String vatNumber; + @Column(name = "EMAIL_JSON") + private String emailJson; + } \ No newline at end of file diff --git a/src/main/java/net/gepafin/tendermanagement/entities/CommunicationEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/CommunicationEntity.java index a1c3ff45..c3d7d61f 100644 --- a/src/main/java/net/gepafin/tendermanagement/entities/CommunicationEntity.java +++ b/src/main/java/net/gepafin/tendermanagement/entities/CommunicationEntity.java @@ -35,4 +35,9 @@ public class CommunicationEntity extends BaseEntity { @JoinColumn(name = "AMENDMENT_ID", referencedColumnName = "id", nullable = false) private ApplicationAmendmentRequestEntity applicationAmendmentRequest; + @Column(name = "INITIATOR_TYPE") + private String intiatorType; + + @Column(name = "DOCUMENTS") + private String documents; } \ No newline at end of file diff --git a/src/main/java/net/gepafin/tendermanagement/enums/CommunicationInitiatorTypeEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/CommunicationInitiatorTypeEnum.java new file mode 100644 index 00000000..8c3e8e9a --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/enums/CommunicationInitiatorTypeEnum.java @@ -0,0 +1,18 @@ +package net.gepafin.tendermanagement.enums; + +public enum CommunicationInitiatorTypeEnum { + + + INSTRUCTOR("INSTRUCTOR"), + BENEFICIARY("BENEFICIARY"); + + private String value; + + CommunicationInitiatorTypeEnum(String value) { + this.value = value; + } + + public String getValue() { + return value; + } +} diff --git a/src/main/java/net/gepafin/tendermanagement/enums/DocumentSourceTypeEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/DocumentSourceTypeEnum.java index e2b121e7..2e10a873 100644 --- a/src/main/java/net/gepafin/tendermanagement/enums/DocumentSourceTypeEnum.java +++ b/src/main/java/net/gepafin/tendermanagement/enums/DocumentSourceTypeEnum.java @@ -5,7 +5,8 @@ public enum DocumentSourceTypeEnum { APPLICATION("APPLICATION"), EVALUATION("EVALUATION"), - AMENDMENT("AMENDMENT"); + AMENDMENT("AMENDMENT"), + COMMUNICATION("COMMUNICATION"); private 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 8d512478..32847535 100644 --- a/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java +++ b/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java @@ -223,7 +223,8 @@ public enum UserActionContextEnum { UPDATE_EXPIRED_CALL("UPDATE_EXPIRED_CALL"), RESEND_EMAIL("RESEND_EMAIL"), SEND_REMINDER_EMAIL("SEND_REMINDER_EMAIL"), - CREATE_SPECIAL_AMENDMENT("CREATE_SPECIAL_AMENDMENT"); + CREATE_SPECIAL_AMENDMENT("CREATE_SPECIAL_AMENDMENT"), + UPDATE_APPLICATION_TO_TECHNICAL_EVALUATION_REJECTED("UPDATE_APPLICATION_TO_TECHNICAL_EVALUATION_REJECTED"); private final String value; diff --git a/src/main/java/net/gepafin/tendermanagement/model/request/ApplicationTechnicalEvaluationRejectedRequest.java b/src/main/java/net/gepafin/tendermanagement/model/request/ApplicationTechnicalEvaluationRejectedRequest.java new file mode 100644 index 00000000..b4a5d93e --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/model/request/ApplicationTechnicalEvaluationRejectedRequest.java @@ -0,0 +1,13 @@ +package net.gepafin.tendermanagement.model.request; + +import lombok.Data; + +import java.util.Map; + +@Data +public class ApplicationTechnicalEvaluationRejectedRequest { + + private Map emailJson; + + +} diff --git a/src/main/java/net/gepafin/tendermanagement/model/request/AppointmentCreationRequest.java b/src/main/java/net/gepafin/tendermanagement/model/request/AppointmentCreationRequest.java index a1c0bb12..71597790 100644 --- a/src/main/java/net/gepafin/tendermanagement/model/request/AppointmentCreationRequest.java +++ b/src/main/java/net/gepafin/tendermanagement/model/request/AppointmentCreationRequest.java @@ -2,6 +2,7 @@ package net.gepafin.tendermanagement.model.request; import lombok.Data; +import java.time.LocalDateTime; import java.util.List; @Data @@ -32,6 +33,7 @@ public class AppointmentCreationRequest { private String codProdotto; private String codOperazione; private Nota nota; + private LocalDateTime dataAppuntamento; } @Data diff --git a/src/main/java/net/gepafin/tendermanagement/model/request/CreateAppointmentRequest.java b/src/main/java/net/gepafin/tendermanagement/model/request/CreateAppointmentRequest.java index 667ba581..870be4a3 100644 --- a/src/main/java/net/gepafin/tendermanagement/model/request/CreateAppointmentRequest.java +++ b/src/main/java/net/gepafin/tendermanagement/model/request/CreateAppointmentRequest.java @@ -2,11 +2,14 @@ package net.gepafin.tendermanagement.model.request; import lombok.Data; +import java.time.LocalDateTime; + @Data public class CreateAppointmentRequest { private Double importoBreveTermine; private Integer durataMesiFinanziamento; private Nota nota; + private LocalDateTime dataAppuntamento; @Data public static class Nota { diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationAmendmentRequestResponse.java b/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationAmendmentRequestResponse.java index c7f1a2eb..c1fda306 100644 --- a/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationAmendmentRequestResponse.java +++ b/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationAmendmentRequestResponse.java @@ -33,4 +33,5 @@ public class ApplicationAmendmentRequestResponse { private ApplicationAmendmentRequestEnum status; private String emailTemplate; private List emailSendResponse; + private List amendmentInitialDocuments; } diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/CommunicationResponseBean.java b/src/main/java/net/gepafin/tendermanagement/model/response/CommunicationResponseBean.java index 170e1318..49e0c5f8 100644 --- a/src/main/java/net/gepafin/tendermanagement/model/response/CommunicationResponseBean.java +++ b/src/main/java/net/gepafin/tendermanagement/model/response/CommunicationResponseBean.java @@ -3,6 +3,7 @@ package net.gepafin.tendermanagement.model.response; import lombok.Data; import java.time.LocalDateTime; +import java.util.List; @Data public class CommunicationResponseBean { @@ -23,6 +24,8 @@ public class CommunicationResponseBean { private Long receiverUserId; private Long amendmentId; + + private List documents; public CommunicationResponseBean(LocalDateTime commentedDate, String comment, String title, LocalDateTime createdDate, LocalDateTime updatedDate, Long amendmentId, Long id) { diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/CommunicationRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/CommunicationRepository.java index 2894d57b..3bbdba34 100644 --- a/src/main/java/net/gepafin/tendermanagement/repositories/CommunicationRepository.java +++ b/src/main/java/net/gepafin/tendermanagement/repositories/CommunicationRepository.java @@ -17,4 +17,6 @@ public interface CommunicationRepository extends JpaRepository findCommentListDetailsByAmendmentId(@Param("amendmentId") Long amendmentId); Optional findByIdAndIsDeletedFalse(Long commentId); + + List findByApplicationAmendmentRequestIdInAndIsDeletedFalse(List amendmentId); } diff --git a/src/main/java/net/gepafin/tendermanagement/service/ApplicationAmendmentRequestService.java b/src/main/java/net/gepafin/tendermanagement/service/ApplicationAmendmentRequestService.java index 5e698107..d8906aa4 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/ApplicationAmendmentRequestService.java +++ b/src/main/java/net/gepafin/tendermanagement/service/ApplicationAmendmentRequestService.java @@ -6,12 +6,13 @@ import net.gepafin.tendermanagement.enums.ApplicationAmendmentRequestEnum; import net.gepafin.tendermanagement.enums.ApplicationStatusTypeEnum; import net.gepafin.tendermanagement.model.request.*; import net.gepafin.tendermanagement.model.response.*; +import org.springframework.web.multipart.MultipartFile; import java.util.List; public interface ApplicationAmendmentRequestService { public ApplicationAmendmentRequestResponse getApplicationDataForAmendment(HttpServletRequest request,Long applicationEvaluationId); - public ApplicationAmendmentRequestResponse createApplicationAmendmentRequest(HttpServletRequest request, Long applicationEvaluationId , ApplicationAmendmentRequest applicationAmendmentRequest); + public ApplicationAmendmentRequestResponse createApplicationAmendmentRequest(HttpServletRequest request, Long applicationEvaluationId , List files, ApplicationAmendmentRequest applicationAmendmentRequest); void deleteApplicationAmendmentRequest(HttpServletRequest request, Long id); ApplicationAmendmentRequestResponse getApplicationAmendmentRequestById(HttpServletRequest request,Long id); List getAllApplicationAmendmentRequest(HttpServletRequest request, Long userId); diff --git a/src/main/java/net/gepafin/tendermanagement/service/ApplicationEvaluationService.java b/src/main/java/net/gepafin/tendermanagement/service/ApplicationEvaluationService.java index 86140ac6..45851c4d 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/ApplicationEvaluationService.java +++ b/src/main/java/net/gepafin/tendermanagement/service/ApplicationEvaluationService.java @@ -3,10 +3,7 @@ package net.gepafin.tendermanagement.service; import jakarta.servlet.http.HttpServletRequest; import net.gepafin.tendermanagement.entities.ApplicationEvaluationEntity; import net.gepafin.tendermanagement.enums.FormActionEnum; -import net.gepafin.tendermanagement.model.request.ApplicationEvaluationFormRequestBean; -import net.gepafin.tendermanagement.model.request.ApplicationEvaluationRequest; -import net.gepafin.tendermanagement.model.request.ApplicationRequestBean; -import net.gepafin.tendermanagement.model.request.EvaluationDocumentRequest; +import net.gepafin.tendermanagement.model.request.*; import net.gepafin.tendermanagement.model.response.*; import java.util.List; @@ -30,4 +27,5 @@ public interface ApplicationEvaluationService { ApplicationEvaluationVersionResponse getApplicationEvaluationVersion(HttpServletRequest request, Long applicationId); + ApplicationEvaluationResponse updateApplicationToTechnicalEvaluationRejected(HttpServletRequest request, ApplicationTechnicalEvaluationRejectedRequest applicationRequest, Long assignedApplicationsId); } diff --git a/src/main/java/net/gepafin/tendermanagement/service/CommunicationService.java b/src/main/java/net/gepafin/tendermanagement/service/CommunicationService.java index 6c99f4a9..00b997b6 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/CommunicationService.java +++ b/src/main/java/net/gepafin/tendermanagement/service/CommunicationService.java @@ -4,9 +4,12 @@ import jakarta.servlet.http.HttpServletRequest; import net.gepafin.tendermanagement.model.request.CommunicationRequestBean; import net.gepafin.tendermanagement.model.response.ApplicationAmendmentResponse; import net.gepafin.tendermanagement.model.response.CommunicationResponseBean; +import org.springframework.web.multipart.MultipartFile; + +import java.util.List; public interface CommunicationService { - CommunicationResponseBean addCommentToAmendmentRequest(HttpServletRequest request ,CommunicationRequestBean communicationRequestBean, Long amendmentId); + CommunicationResponseBean addCommentToAmendmentRequest(HttpServletRequest request , CommunicationRequestBean communicationRequestBean, Long amendmentId, List files); String deleteComment(HttpServletRequest request,Long amendmentId, Long commentId); 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 8926971f..432f4add 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationAmendmentRequestServiceImpl.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationAmendmentRequestServiceImpl.java @@ -14,6 +14,7 @@ import net.gepafin.tendermanagement.repositories.ApplicationAmendmentRequestRepo import net.gepafin.tendermanagement.repositories.ApplicationEvaluationRepository; import net.gepafin.tendermanagement.service.ApplicationAmendmentRequestService; import net.gepafin.tendermanagement.service.UserService; +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; @@ -21,8 +22,10 @@ import net.gepafin.tendermanagement.web.rest.api.errors.Status; 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; +import java.util.Map; import java.util.Optional; @Service @@ -50,10 +53,15 @@ public class ApplicationAmendmentRequestServiceImpl implements ApplicationAmendm @Override @Transactional(rollbackFor = Exception.class) - public ApplicationAmendmentRequestResponse createApplicationAmendmentRequest(HttpServletRequest request, Long applicationEvaluationId , ApplicationAmendmentRequest applicationAmendmentRequest) { + public ApplicationAmendmentRequestResponse createApplicationAmendmentRequest(HttpServletRequest request, Long applicationEvaluationId , List files, ApplicationAmendmentRequest applicationAmendmentRequest) { Optional entityOptional = applicationEvaluationRepository.findByIdAndIsDeletedFalse(applicationEvaluationId); entityOptional.ifPresent(applicationEvaluationEntity -> validator.validatePreInstructor(request, applicationEvaluationEntity.getUserId())); - return applicationAmendmentRequestDao.createApplicationAmendmentRequest(applicationEvaluationId,applicationAmendmentRequest); + Map userInfo = validator.getUserInfoFromToken(request); + Long userId = validator.getUserId(userInfo); + if(files!=null) { + files.forEach(Utils::validateFileType); + } + return applicationAmendmentRequestDao.createApplicationAmendmentRequest(applicationEvaluationId,files,applicationAmendmentRequest,userId); } @Override diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationEvaluationServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationEvaluationServiceImpl.java index 650acdc1..4033dd70 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationEvaluationServiceImpl.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationEvaluationServiceImpl.java @@ -9,6 +9,7 @@ import net.gepafin.tendermanagement.entities.AssignedApplicationsEntity; import net.gepafin.tendermanagement.entities.UserEntity; import net.gepafin.tendermanagement.model.request.ApplicationEvaluationFormRequestBean; import net.gepafin.tendermanagement.model.request.ApplicationEvaluationRequest; +import net.gepafin.tendermanagement.model.request.ApplicationTechnicalEvaluationRejectedRequest; import net.gepafin.tendermanagement.model.response.ApplicationEvaluationFormResponse; import net.gepafin.tendermanagement.model.response.ApplicationEvaluationResponse; import net.gepafin.tendermanagement.model.response.ApplicationEvaluationResponseBean; @@ -106,6 +107,10 @@ public class ApplicationEvaluationServiceImpl implements ApplicationEvaluationSe return applicationEvaluationDao.getApplicationEvaluationVersion(request,applicationId); } + @Override + public ApplicationEvaluationResponse updateApplicationToTechnicalEvaluationRejected(HttpServletRequest request, ApplicationTechnicalEvaluationRejectedRequest applicationRequest, Long assignedApplicationsId) { + return applicationEvaluationDao.updateApplicationToTechnicalEvaluationRejected(applicationRequest,assignedApplicationsId); + } } diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/CommunicationServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/CommunicationServiceImpl.java index ed51cc7a..e0f125ae 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/CommunicationServiceImpl.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/CommunicationServiceImpl.java @@ -12,7 +12,9 @@ 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; @Service @@ -29,14 +31,14 @@ public class CommunicationServiceImpl implements CommunicationService { @Override @Transactional(rollbackFor = Exception.class) - public CommunicationResponseBean addCommentToAmendmentRequest(HttpServletRequest request ,CommunicationRequestBean communicationRequestBean, Long amendmentId) { + public CommunicationResponseBean addCommentToAmendmentRequest(HttpServletRequest request , CommunicationRequestBean communicationRequestBean, Long amendmentId, List files) { ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity = applicationAmendmentRequestDao.validateApplicationAmendmentRequest(amendmentId); if (Boolean.FALSE.equals(validator.checkIsBeneficiary()) && Boolean.FALSE.equals(validator.checkIsConfidi())) { validator.validatePreInstructor(request, applicationAmendmentRequestEntity.getApplicationEvaluationEntity().getUserId()); } else { validator.validateUserId(request, applicationAmendmentRequestEntity.getApplicationEvaluationEntity().getAssignedApplicationsEntity().getApplication().getUserId()); } - return communicationDao.addCommentToAmendmentRequest(request,communicationRequestBean, amendmentId); + return communicationDao.addCommentToAmendmentRequest(request,communicationRequestBean, amendmentId,files); } @Override diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/S3ReUploadMigrationService.java b/src/main/java/net/gepafin/tendermanagement/service/impl/S3ReUploadMigrationService.java index dac565e7..fdb09116 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/S3ReUploadMigrationService.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/S3ReUploadMigrationService.java @@ -10,6 +10,7 @@ import lombok.extern.slf4j.Slf4j; import net.gepafin.tendermanagement.dao.DocumentDao; import net.gepafin.tendermanagement.dao.S3PathConfig; import net.gepafin.tendermanagement.entities.ApplicationEntity; +import net.gepafin.tendermanagement.entities.CommunicationEntity; import net.gepafin.tendermanagement.entities.DocumentEntity; import net.gepafin.tendermanagement.enums.DocumentSourceTypeEnum; import net.gepafin.tendermanagement.repositories.*; @@ -25,6 +26,7 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.List; +import java.util.Optional; @Slf4j @Service @@ -73,6 +75,9 @@ public class S3ReUploadMigrationService { @Autowired private ApplicationEvaluationRepository applicationEvaluationRepository; + @Autowired + private CommunicationRepository communicationRepository; + @Autowired private DocumentDao documentDao; @@ -108,6 +113,7 @@ public class S3ReUploadMigrationService { Long applicationId = null; Long amendmentId = null; Long evaluationId = null; + Long communicationId=null; if (DocumentSourceTypeEnum.CALL.getValue().equalsIgnoreCase(document.getSource())) { callId = document.getSourceId(); } else if (DocumentSourceTypeEnum.APPLICATION.getValue().equalsIgnoreCase(document.getSource())) { @@ -125,10 +131,16 @@ public class S3ReUploadMigrationService { ApplicationEntity applicationEntity = applicationEvaluationRepository.findApplicationByEvaluationId(evaluationId); applicationId = applicationEntity.getId(); callId = applicationEntity.getCall().getId(); + }else if(DocumentSourceTypeEnum.COMMUNICATION.getValue().equalsIgnoreCase(document.getSource())){ + communicationId = document.getSourceId(); + Optional communicationEntity=communicationRepository.findByIdAndIsDeletedFalse(communicationId); + ApplicationEntity applicationEntity =communicationEntity.get().getApplicationAmendmentRequest().getApplicationEvaluationEntity().getAssignedApplicationsEntity().getApplication(); + applicationId = applicationEntity.getId(); + callId = applicationEntity.getCall().getId(); } - documentDao.deleteFileFromS3(document,callId,applicationId,amendmentId); + documentDao.deleteFileFromS3(document,callId,applicationId,amendmentId,communicationId); processDocuments++; } catch (Exception e) { @@ -219,10 +231,10 @@ public class S3ReUploadMigrationService { Long callId; if (sourceType.equals(DocumentSourceTypeEnum.CALL)) { - return s3ConfigBean.generateDocumentPath(sourceType, document.getSourceId(), 0L,0L); + return s3ConfigBean.generateDocumentPath(sourceType, document.getSourceId(), 0L,0L,0L); } else { callId = applicationRepository.findCallIdById(document.getSourceId()); - return s3ConfigBean.generateDocumentPath(sourceType, callId, document.getSourceId(),0L); + return s3ConfigBean.generateDocumentPath(sourceType, callId, document.getSourceId(),0L,0L); } } diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/UserSignedAndDelegationServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/UserSignedAndDelegationServiceImpl.java index d5bd4c3c..e6ba7821 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/UserSignedAndDelegationServiceImpl.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/UserSignedAndDelegationServiceImpl.java @@ -139,7 +139,7 @@ public class UserSignedAndDelegationServiceImpl { private String generateNewS3PathForDelegationDoc() { - return s3ConfigBean.generateDocumentPathForOther(DocOtherSourceTypeEnum.USER_DELEGATION, 0L, 0L,0L); + return s3ConfigBean.generateDocumentPathForOther(DocOtherSourceTypeEnum.USER_DELEGATION, 0L, 0L,0L,0L); } private String generateNewS3PathForUserSignedDoc(ApplicationSignedDocumentEntity document) { diff --git a/src/main/java/net/gepafin/tendermanagement/util/Utils.java b/src/main/java/net/gepafin/tendermanagement/util/Utils.java index 28dca3d7..b9541759 100644 --- a/src/main/java/net/gepafin/tendermanagement/util/Utils.java +++ b/src/main/java/net/gepafin/tendermanagement/util/Utils.java @@ -1095,6 +1095,22 @@ public class Utils { return "Invalid amount format"; } } + public static void validateEmailJson(Map emailJson) { + for (Map.Entry entry : emailJson.entrySet()) { + if (isEmpty(entry.getKey())) { + throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.INVALID_EMAIL_JSON)); + } + } + validateJsonKeys(emailJson, GepafinConstant.MANUAL_EMAIL_KEYS); + } + private static void validateJsonKeys(Map actionJson, List validkeys) { + for (String key : validkeys) { + if (!actionJson.containsKey(key)) { + throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.INVALID_EMAIL_JSON)); + } + } + + } } 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 9fe94bb5..033f9fd6 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 @@ -18,6 +18,7 @@ import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; import java.util.List; @@ -44,10 +45,16 @@ public interface ApplicationAmendmentRequestApi { @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 = "", produces = "application/json") - ResponseEntity> createApplicationAmendmentRequest(HttpServletRequest request, - @Parameter(description = "Application Evaluation Id", required = true) @RequestParam Long applicationEvaluationId, - @Valid @RequestBody ApplicationAmendmentRequest applicationAmendmentRequest); + @PostMapping(value = "", consumes = MediaType.MULTIPART_FORM_DATA_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) + ResponseEntity> createApplicationAmendmentRequest( + HttpServletRequest request, + @Parameter(description = "Application Evaluation Id", required = true) + @RequestParam Long applicationEvaluationId, + @Parameter(description = "List of files to upload", required = false) + @RequestPart(required = false) List files, + @Parameter(description = "Amendment details as JSON", required = true) + @RequestPart("applicationAmendmentRequest") ApplicationAmendmentRequest applicationAmendmentRequest); + @Operation(summary = "Api to delete application amendment request", responses = { diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/ApplicationEvaluationApi.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/ApplicationEvaluationApi.java index 4798e078..b2ff117e 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/ApplicationEvaluationApi.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/ApplicationEvaluationApi.java @@ -8,10 +8,7 @@ import io.swagger.v3.oas.annotations.responses.ApiResponse; import jakarta.servlet.http.HttpServletRequest; import jakarta.validation.Valid; import net.gepafin.tendermanagement.enums.FormActionEnum; -import net.gepafin.tendermanagement.model.request.ApplicationEvaluationFormRequestBean; -import net.gepafin.tendermanagement.model.request.ApplicationEvaluationRequest; -import net.gepafin.tendermanagement.model.request.ApplicationRequestBean; -import net.gepafin.tendermanagement.model.request.EvaluationDocumentRequest; +import net.gepafin.tendermanagement.model.request.*; import net.gepafin.tendermanagement.model.response.*; import net.gepafin.tendermanagement.model.util.Response; import net.gepafin.tendermanagement.web.rest.api.errors.ErrorConstants; @@ -104,5 +101,18 @@ public interface ApplicationEvaluationApi { @Parameter(description = "The application id", required = true) @PathVariable("id") Long id); + @Operation(summary = "API to update Application to TECHNICAL EVALUATION REJECTED", + 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 = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) + }) + @PutMapping(value = "/{assignedApplicationsId}/technicalEvaluationRejected", produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE) + ResponseEntity> updateApplicationToTechnicalEvaluationRejected( + HttpServletRequest request, + @Parameter(description = "Assigned Application ID", required = true) @PathVariable("assignedApplicationsId") Long assignedApplicationsId, + @Parameter(description = "Application Request Body", required = true) @Valid @RequestBody ApplicationTechnicalEvaluationRejectedRequest applicationRequest); } diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/CommunicationApi.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/CommunicationApi.java index 01070a4e..78ecf16e 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/CommunicationApi.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/CommunicationApi.java @@ -16,12 +16,10 @@ import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import java.util.List; @Validated public interface CommunicationApi { @@ -32,10 +30,11 @@ public interface CommunicationApi { @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 = "/{amendmentId}", produces = { "application/json" }) + @PostMapping(value = "/{amendmentId}", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) @PreAuthorize("hasRole('ROLE_PRE_INSTRUCTOR') || hasRole('ROLE_BENEFICIARY') || hasRole('ROLE_INSTRUCTOR_MANAGER') || hasRole('ROLE_CONFIDI')") - ResponseEntity> addCommentToAmendmentRequest(HttpServletRequest request, - @RequestBody @Parameter CommunicationRequestBean communicationResponseBean, @PathVariable(value = "amendmentId") Long amendmentId); + ResponseEntity> addCommentToAmendmentRequest(HttpServletRequest request, @Parameter(description = "List of files to upload", required = false) + @RequestPart(required = false) List files, + @Parameter(description = "communication request body" ,required=true) @RequestPart CommunicationRequestBean communicationResponseBean, @PathVariable(value = "amendmentId") Long amendmentId); @Operation(summary = "API to Get Amendment Request Comment", responses = { @ApiResponse(responseCode = "200", description = "OK"), @ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = @ExampleObject(value = 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 797cce3a..12906aef 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 @@ -1,5 +1,7 @@ package net.gepafin.tendermanagement.web.rest.api.impl; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; import jakarta.servlet.http.HttpServletRequest; import lombok.extern.log4j.Log4j2; import net.gepafin.tendermanagement.config.Translator; @@ -19,6 +21,8 @@ import org.springframework.http.HttpStatus; 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 java.util.List; @RestController @@ -26,6 +30,9 @@ import java.util.List; @Log4j2 public class ApplicationAmendmentRequestController implements ApplicationAmendmentRequestApi { + @Autowired + private ObjectMapper mapper; + @Autowired ApplicationAmendmentRequestService applicationAmendmentRequestService; @@ -45,13 +52,18 @@ public class ApplicationAmendmentRequestController implements ApplicationAmendme } @Override - public ResponseEntity> createApplicationAmendmentRequest(HttpServletRequest request, Long applicationEvaluationId, ApplicationAmendmentRequest applicationAmendmentRequest) { - + public ResponseEntity> createApplicationAmendmentRequest(HttpServletRequest request, Long applicationEvaluationId, List files, ApplicationAmendmentRequest applicationAmendmentRequest) { +// ApplicationAmendmentRequest data=null; +// try { +// data = mapper.readValue(applicationAmendmentRequest,ApplicationAmendmentRequest.class); +// } catch (JsonProcessingException e) { +// throw new RuntimeException(e); +// } /** This code is responsible for creating user action logs for the "Create Application Amendment" operation. **/ loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.INSERT) .actionContext(UserActionContextEnum.CREATE_AMENDMENT).build()); - ApplicationAmendmentRequestResponse applicationAmendmentRequestResponse = applicationAmendmentRequestService.createApplicationAmendmentRequest(request,applicationEvaluationId,applicationAmendmentRequest); + ApplicationAmendmentRequestResponse applicationAmendmentRequestResponse = applicationAmendmentRequestService.createApplicationAmendmentRequest(request,applicationEvaluationId,files,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/java/net/gepafin/tendermanagement/web/rest/api/impl/ApplicationEvaluationApiController.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/ApplicationEvaluationApiController.java index 2f6bbcb3..21739f40 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/ApplicationEvaluationApiController.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/ApplicationEvaluationApiController.java @@ -118,4 +118,15 @@ public class ApplicationEvaluationApiController implements ApplicationEvaluation .body(new Response<>(applicationEvaluationVersionResponse, Status.SUCCESS, Translator.toLocale(GepafinConstant.GET_APPLICATION_EVALUATION_VERSION_SUCCESS_MSG))); } + @Override + public ResponseEntity> updateApplicationToTechnicalEvaluationRejected(HttpServletRequest request, Long assignedApplicationsId, ApplicationTechnicalEvaluationRejectedRequest applicationRequest) { + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.VIEW).actionContext(UserActionContextEnum.UPDATE_APPLICATION_TO_TECHNICAL_EVALUATION_REJECTED).build()); + + ApplicationEvaluationResponse applicationEvaluationVersionResponse = applicationEvaluationService.updateApplicationToTechnicalEvaluationRejected(request,applicationRequest,assignedApplicationsId); + + return ResponseEntity.status(HttpStatus.OK) + .body(new Response<>(null, Status.SUCCESS, Translator.toLocale(GepafinConstant.UPDATE_APPLICATION_TECHNICAL_EVALUATION_REJECTED_MSG))); + + } + } diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/CommunicationController.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/CommunicationController.java index 15552e95..5473d560 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/CommunicationController.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/CommunicationController.java @@ -19,6 +19,9 @@ import org.springframework.http.HttpStatus; 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 java.util.List; @RestController @RequestMapping("${openapi.gepafin.base-path:/v1/communication}") @@ -31,13 +34,13 @@ public class CommunicationController implements CommunicationApi { private LoggingUtil loggingUtil; @Override - public ResponseEntity> addCommentToAmendmentRequest(HttpServletRequest request, CommunicationRequestBean communicationRequestBean, - Long amendmentId) { + public ResponseEntity> addCommentToAmendmentRequest(HttpServletRequest request, List files, CommunicationRequestBean communicationRequestBean, + Long amendmentId) { /** This code is responsible for creating user action logs for the "Adding comment to amendment request" operation. **/ loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.INSERT).actionContext(UserActionContextEnum.ADD_COMMENT_TO_AMENDMENT_REQUEST).build()); - CommunicationResponseBean communicationResponseBean = communicationService.addCommentToAmendmentRequest(request,communicationRequestBean, amendmentId); + CommunicationResponseBean communicationResponseBean = communicationService.addCommentToAmendmentRequest(request,communicationRequestBean, amendmentId,files); return ResponseEntity.status(HttpStatus.CREATED) .body(new Response<>(communicationResponseBean, Status.SUCCESS, Translator.toLocale(GepafinConstant.COMMUNICATION_ADDED_TO_AMENDMENT_REQUEST_SUCCESS))); } 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 d99cb334..ae84bbd2 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 @@ -3034,5 +3034,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + UNIQUE_UUID = 'p4lk3bcx1RStqTaIVVbXs' + + diff --git a/src/main/resources/message_en.properties b/src/main/resources/message_en.properties index 684a6006..4357cac5 100644 --- a/src/main/resources/message_en.properties +++ b/src/main/resources/message_en.properties @@ -413,4 +413,7 @@ email.pec.cannot.null=Email pec is required. user.request.completed=User request completed successfully. end.date.greater.than.now=End date must be greater than the current date and time. pec.email.required=PEC email is required. +application.technical.evaluation.rejected.success=Application changes to status application technical evaluation rejected successfully. +invalid.email.json=Invalid email json. + diff --git a/src/main/resources/message_it.properties b/src/main/resources/message_it.properties index 92a96cb0..8a027a3a 100644 --- a/src/main/resources/message_it.properties +++ b/src/main/resources/message_it.properties @@ -404,4 +404,5 @@ email.pec.cannot.null=L'indirizzo email pec user.request.completed=Richiesta utente completata con successo. end.date.greater.than.now=La data di fine deve essere successiva alla data e all'ora correnti. pec.email.required=Obbligatorio l'indirizzo e-mail PEC. - +application.technical.evaluation.rejected.success=Lo stato dell'applicazione cambia: valutazione tecnica dell'applicazione rifiutata con successo. +invalid.email.json=Codice email json non valido. From c469b08e1860ca6f70382c35c1462cfe2c590401 Mon Sep 17 00:00:00 2001 From: rajesh Date: Tue, 14 Oct 2025 19:41:00 +0530 Subject: [PATCH 46/75] Updated response of communication API --- .../dao/ApplicationEvaluationDao.java | 2 +- .../tendermanagement/dao/AppointmentDao.java | 3 +- .../dao/CommunicationDao.java | 10 +++- .../dao/EmailNotificationDao.java | 46 +++++++++++-------- .../request/AppointmentCreationRequest.java | 1 + .../repositories/CommunicationRepository.java | 8 ++-- 6 files changed, 42 insertions(+), 28 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java index fbbd5a50..f5ba0615 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java @@ -2623,7 +2623,7 @@ public class ApplicationEvaluationDao { application.setStatus(ApplicationStatusForEvaluation.TECHNICAL_EVALUATION_REJECTED.getValue()); log.info("Application status updated to {} for applicationId: {}", ApplicationStatusForEvaluation.TECHNICAL_EVALUATION_REJECTED, application.getId()); - emailNotificationDao.sendMailForApplicationTechnicalEvaluationRejected(application, hub, existingEntity,applicationRequest.getEmailJson()); + emailNotificationDao.sendMailForApplicationTechnicalEvaluationRejected(application, hub, existingEntity); application.setDateRejected(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); application.setEmailJson(Utils.convertMapIntoJsonString(applicationRequest.getEmailJson())); emailSendResponse = emailDao.buildEmailSendResponseFromRequest(request); diff --git a/src/main/java/net/gepafin/tendermanagement/dao/AppointmentDao.java b/src/main/java/net/gepafin/tendermanagement/dao/AppointmentDao.java index fcccd5e6..cbd2f300 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/AppointmentDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/AppointmentDao.java @@ -1144,10 +1144,9 @@ public class AppointmentDao { richiestaCliente.setNota(requestNota); richiestaCliente.setDurataMesiFinanziamento(createAppointmentRequest.getDurataMesiFinanziamento()); richiestaCliente.setImportoBreveTermine(createAppointmentRequest.getImportoBreveTermine()); - richiestaCliente.setDataAppuntamento(createAppointmentRequest.getDataAppuntamento()); richiestaClienteList.add(richiestaCliente); } - + input.setDataAppuntamento(createAppointmentRequest.getDataAppuntamento()); input.setRichiestaCliente(richiestaClienteList); appointmentCreationRequest.setInput(input); return appointmentCreationRequest; diff --git a/src/main/java/net/gepafin/tendermanagement/dao/CommunicationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/CommunicationDao.java index 686ac828..81960f9d 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/CommunicationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/CommunicationDao.java @@ -120,11 +120,17 @@ public class CommunicationDao { public ApplicationAmendmentResponse getAmendmentComments(Long amendmentId) { ApplicationAmendmentRequestEntity amendmentData = applicationAmendmentRequestService.validateApplicationAmendmentRequest(amendmentId); - List commentsList = communicationRepository.findCommentListDetailsByAmendmentId(amendmentId); + List commentsList = communicationRepository.findByApplicationAmendmentRequestIdAndIsDeletedFalse(amendmentId); if (commentsList == null) { throw new CustomValidationException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.COMMENT_NOT_FOUND)); } - return new ApplicationAmendmentResponse(amendmentData, commentsList); + List communicationResponseBeans=new ArrayList<>(); + for(CommunicationEntity communicationEntity:commentsList){ + List communicationDocumentBeans=getDocumentResponseBean(communicationEntity); + CommunicationResponseBean communicationResponseBean=convertToCommunicationResponseBean(communicationEntity,communicationDocumentBeans); + communicationResponseBeans.add(communicationResponseBean); + } + return new ApplicationAmendmentResponse(amendmentData, communicationResponseBeans); } public CommunicationResponseBean updateAmendmentComment(CommunicationRequestBean communicationRequestBean, Long amendmentId, Long commentId) { diff --git a/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java index 3af44ecb..cc676a7b 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java @@ -429,28 +429,36 @@ public class EmailNotificationDao { throw new IllegalArgumentException("Failed to parse email configuration JSON", e); } } - public void sendMailForApplicationTechnicalEvaluationRejected(ApplicationEntity applicationEntity,HubEntity hub,ApplicationEvaluationEntity applicationEvaluationEntity,Map emailJson) { - HubEntity hubEntity = hubService.valdateHub(applicationEntity.getHubId()); - SystemEmailTemplateResponse systemEmailTemplateResponse=new SystemEmailTemplateResponse(); - systemEmailTemplateResponse.setSubject((String) emailJson.get("subject")); - systemEmailTemplateResponse.setHtmlContent((String) emailJson.get("message")); - Map subjectPlaceholders = new HashMap<>(); - CompanyEntity company = companyService.validateCompany(applicationEntity.getCompanyId()); - subjectPlaceholders.put("{{call_name}}", applicationEntity.getCall().getName()); - subjectPlaceholders.put("{{company_name}}", company.getCompanyName()); + public void sendMailForApplicationTechnicalEvaluationRejected(ApplicationEntity applicationEntity,HubEntity hub,ApplicationEvaluationEntity applicationEvaluationEntity) { + Map bodyPlaceholders = prepareEmailPlaceholdersForTechnicalEvaluationRejected(applicationEntity,hub,applicationEvaluationEntity); - String subject = Utils.replacePlaceholders(systemEmailTemplateResponse.getSubject(), subjectPlaceholders); - String body = Utils.replacePlaceholders(systemEmailTemplateResponse.getHtmlContent(), bodyPlaceholders); - SystemEmailTemplateResponse systemEmailTemplateResponse1=new SystemEmailTemplateResponse(); - systemEmailTemplateResponse1.setSubject(subject); - systemEmailTemplateResponse1.setHtmlContent(body); - systemEmailTemplateResponse1.setEmailScenario(EmailScenarioTypeEnum.APPLICATION_TECHNICAL_EVALUATION_REJECTED); - EmailContentResponse emailContentResponse=new EmailContentResponse(subject,body,systemEmailTemplateResponse1); - UserEntity userEntity = userService.validateUser(applicationEntity.getUserId()); - sendEmails(applicationEntity, userEntity, null,null,emailContentResponse.getSystemEmailTemplateResponse(),emailContentResponse.getSubject(),emailContentResponse.getBody()); - + sendEmail(applicationEntity, SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum.INADMISSIBILITY_NOTIFICATION_DUE_TO_TECHNICAL_EVALUATION_FAILURE, bodyPlaceholders, null, + null); } + +// public void sendMailForApplicationTechnicalEvaluationRejected(ApplicationEntity applicationEntity,HubEntity hub,ApplicationEvaluationEntity applicationEvaluationEntity,Map emailJson) { +// +// HubEntity hubEntity = hubService.valdateHub(applicationEntity.getHubId()); +// SystemEmailTemplateResponse systemEmailTemplateResponse=new SystemEmailTemplateResponse(); +// systemEmailTemplateResponse.setSubject((String) emailJson.get("subject")); +// systemEmailTemplateResponse.setHtmlContent((String) emailJson.get("message")); +// Map subjectPlaceholders = new HashMap<>(); +// CompanyEntity company = companyService.validateCompany(applicationEntity.getCompanyId()); +// subjectPlaceholders.put("{{call_name}}", applicationEntity.getCall().getName()); +// subjectPlaceholders.put("{{company_name}}", company.getCompanyName()); +// Map bodyPlaceholders = prepareEmailPlaceholdersForTechnicalEvaluationRejected(applicationEntity,hub,applicationEvaluationEntity); +// String subject = Utils.replacePlaceholders(systemEmailTemplateResponse.getSubject(), subjectPlaceholders); +// String body = Utils.replacePlaceholders(systemEmailTemplateResponse.getHtmlContent(), bodyPlaceholders); +// SystemEmailTemplateResponse systemEmailTemplateResponse1=new SystemEmailTemplateResponse(); +// systemEmailTemplateResponse1.setSubject(subject); +// systemEmailTemplateResponse1.setHtmlContent(body); +// systemEmailTemplateResponse1.setEmailScenario(EmailScenarioTypeEnum.APPLICATION_TECHNICAL_EVALUATION_REJECTED); +// EmailContentResponse emailContentResponse=new EmailContentResponse(subject,body,systemEmailTemplateResponse1); +// UserEntity userEntity = userService.validateUser(applicationEntity.getUserId()); +// sendEmails(applicationEntity, userEntity, null,null,emailContentResponse.getSystemEmailTemplateResponse(),emailContentResponse.getSubject(),emailContentResponse.getBody()); +// +// } public Map prepareEmailPlaceholdersForTechnicalEvaluationRejected(ApplicationEntity applicationEntity,HubEntity hub,ApplicationEvaluationEntity applicationEvaluationEntity) { Map bodyPlaceholders = new HashMap<>(); bodyPlaceholders.put("{{call_name}}", applicationEntity.getCall().getName()); diff --git a/src/main/java/net/gepafin/tendermanagement/model/request/AppointmentCreationRequest.java b/src/main/java/net/gepafin/tendermanagement/model/request/AppointmentCreationRequest.java index 71597790..8a16a021 100644 --- a/src/main/java/net/gepafin/tendermanagement/model/request/AppointmentCreationRequest.java +++ b/src/main/java/net/gepafin/tendermanagement/model/request/AppointmentCreationRequest.java @@ -15,6 +15,7 @@ public class AppointmentCreationRequest { private Long id; private String ndg; private List richiestaCliente; + private LocalDateTime dataAppuntamento; } @Data diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/CommunicationRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/CommunicationRepository.java index 3bbdba34..751493bf 100644 --- a/src/main/java/net/gepafin/tendermanagement/repositories/CommunicationRepository.java +++ b/src/main/java/net/gepafin/tendermanagement/repositories/CommunicationRepository.java @@ -11,10 +11,10 @@ import java.util.Optional; public interface CommunicationRepository extends JpaRepository { - @Query("SELECT new net.gepafin.tendermanagement.model.response.CommunicationResponseBean( " + "c.commentedDate, c.communicationComment, c.communicationTitle, c.createdDate, c" + - ".updatedDate, " + "c.applicationAmendmentRequest.id, c.senderUserId, c.receiverUserId, c.id " + ") " + "FROM CommunicationEntity c " + "WHERE c" + - ".applicationAmendmentRequest.id = :amendmentId AND c.isDeleted = false") - List findCommentListDetailsByAmendmentId(@Param("amendmentId") Long amendmentId); + // @Query("SELECT new net.gepafin.tendermanagement.model.response.CommunicationResponseBean( " + "c.commentedDate, c.communicationComment, c.communicationTitle, c.createdDate, c" + +// ".updatedDate, " + "c.applicationAmendmentRequest.id, c.senderUserId, c.receiverUserId, c.id " + ") " + "FROM CommunicationEntity c " + "WHERE c" + +// ".applicationAmendmentRequest.id = :amendmentId AND c.isDeleted = false") + List findByApplicationAmendmentRequestIdAndIsDeletedFalse(Long amendmentId); Optional findByIdAndIsDeletedFalse(Long commentId); From 9a93c470abb1de2f19e87842a44b47f00d1274be Mon Sep 17 00:00:00 2001 From: rajesh Date: Tue, 14 Oct 2025 20:58:43 +0530 Subject: [PATCH 47/75] Fixed document issue in communication --- .../tendermanagement/dao/DocumentDao.java | 29 ++++++++++--------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/DocumentDao.java b/src/main/java/net/gepafin/tendermanagement/dao/DocumentDao.java index 4f87d2bc..597e3c4f 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/DocumentDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/DocumentDao.java @@ -99,19 +99,22 @@ public class DocumentDao { log.info("Uploading files userId={}, sourceType={}, fileType={}", userId,sourceType,fileType); List documentEntities = new ArrayList<>(); Long source = resolveSourceId(sourceId, sourceType); - for (MultipartFile file : files) { - log.info("Uploading file '{}'", file.getOriginalFilename()); - UploadFileOnAmazonS3Response uploadFileOnAmazonS3Response = uploadFileOnAmazonS3(file, sourceType, sourceId); - if (uploadFileOnAmazonS3Response != null) { - DocumentEntity documentEntity = new DocumentEntity(); - documentEntity.setFileName(uploadFileOnAmazonS3Response.getFileName()); - documentEntity.setSource(sourceType.getValue()); - documentEntity.setSourceId(source); - documentEntity.setType(fileType.getValue()); - documentEntity.setFilePath(uploadFileOnAmazonS3Response.getFilePath()); - documentEntity.setIsDeleted(false); - documentEntity.setUploadedBy(userId); - documentEntities.add(documentEntity); + + if(files!=null) { + for (MultipartFile file : files) { + log.info("Uploading file '{}'", file.getOriginalFilename()); + UploadFileOnAmazonS3Response uploadFileOnAmazonS3Response = uploadFileOnAmazonS3(file, sourceType, sourceId); + if (uploadFileOnAmazonS3Response != null) { + DocumentEntity documentEntity = new DocumentEntity(); + documentEntity.setFileName(uploadFileOnAmazonS3Response.getFileName()); + documentEntity.setSource(sourceType.getValue()); + documentEntity.setSourceId(source); + documentEntity.setType(fileType.getValue()); + documentEntity.setFilePath(uploadFileOnAmazonS3Response.getFilePath()); + documentEntity.setIsDeleted(false); + documentEntity.setUploadedBy(userId); + documentEntities.add(documentEntity); + } } } documentRepository.saveAll(documentEntities); From 33009b232e73a6091c0d1fc54613bdbf989e4d3e Mon Sep 17 00:00:00 2001 From: rajesh Date: Wed, 15 Oct 2025 15:02:53 +0530 Subject: [PATCH 48/75] Disabled pec config --- src/main/resources/application-dev.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/resources/application-dev.properties b/src/main/resources/application-dev.properties index 80e20599..356735fb 100644 --- a/src/main/resources/application-dev.properties +++ b/src/main/resources/application-dev.properties @@ -10,7 +10,7 @@ spring.h2.console.enabled=true isVatCheckGloballyDisabled = false isMailSendingEnabled = true -isPecServiceEnabled = true +isPecServiceEnabled = false #default_System_Receiver_Email=antonio.manca@bflows.net gepafin_email=rinaldo.bonazzo@bflows.net rinaldo_email=rinaldo.bonazzo@bflows.net @@ -19,7 +19,7 @@ default.hub.uuid=p4lk3bcx1RStqTaIVVbXs #Login to Odessa, Appointment Creation, Upload document Configuration appointment.base.url=https://demo.galileonetwork.it/gateway/rest appointment.portal.user=UtenzaAPIPortal@621 -appointment.portal.password=u13nzaAP1P0rtal! +appointment.portal.password=Sardegna2025! appointment.portal.source=GEPAFINPORTAL appointment.portal.context=GEPAFINPORTAL From 21762d2e115a4b43cd952132a930bfa8633601b3 Mon Sep 17 00:00:00 2001 From: rajesh Date: Thu, 16 Oct 2025 12:51:26 +0530 Subject: [PATCH 49/75] Change in response of amendment for email template --- .../dao/ApplicationAmendmentRequestDao.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java index 22f7731a..76d17211 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java @@ -595,7 +595,12 @@ public class ApplicationAmendmentRequestDao { if (includeEmailContent) { Map bodyPlaceholders = emailNotificationDao.prepareEmailPlaceholders(applicationEntity, entity); - EmailContentResponse emailContent = emailNotificationDao.prepareEmailContent(applicationEntity, SystemEmailTemplatesEntityTypeEnum.DOCUMENTATION_INTEGRATION_REQUEST, hubEntity, bodyPlaceholders); + EmailContentResponse emailContent =null; + if(entity.getType()!=null && entity.getType().equals(ApplicationAmendmentRequestTypeEnum.SPECIAL.getValue())){ + emailContent=emailNotificationDao.prepareEmailContent(applicationEntity, SystemEmailTemplatesEntityTypeEnum.SPECIAL_APPLICATION_AMENDMENT_REQUESTED, hubEntity, bodyPlaceholders); + }else { + emailContent = emailNotificationDao.prepareEmailContent(applicationEntity, SystemEmailTemplatesEntityTypeEnum.DOCUMENTATION_INTEGRATION_REQUEST, hubEntity, bodyPlaceholders); + } String body = emailContent.getBody(); response.setEmailTemplate(body); } From e83e121ba0457df6e93a6741916d102d0082f0fe Mon Sep 17 00:00:00 2001 From: rajesh Date: Thu, 16 Oct 2025 17:40:56 +0530 Subject: [PATCH 50/75] Done changes related to application rejected --- .../constants/GepafinConstant.java | 1 + .../dao/ApplicationAmendmentRequestDao.java | 2 + .../dao/ApplicationEvaluationDao.java | 99 +++++++++++++++---- .../dao/AssignedApplicationsDao.java | 2 +- .../dao/CommunicationDao.java | 5 +- .../dao/EmailNotificationDao.java | 14 ++- .../entities/ApplicationEntity.java | 9 +- .../ApplicationEvaluationFormRequestBean.java | 1 + .../request/ApplicationEvaluationRequest.java | 1 + .../ApplicationAmendmentRequestResponse.java | 2 + .../ApplicationEvaluationResponse.java | 1 + .../service/ApplicationEvaluationService.java | 5 +- .../service/CommunicationService.java | 3 +- .../ApplicationEvaluationServiceImpl.java | 9 +- .../impl/CommunicationServiceImpl.java | 3 +- .../rest/api/ApplicationEvaluationApi.java | 15 +-- .../web/rest/api/CommunicationApi.java | 3 +- .../ApplicationEvaluationApiController.java | 9 +- .../api/impl/CommunicationController.java | 5 +- .../db/changelog/db.changelog-1.0.0.xml | 13 +++ ...ate_of_application_rejected_16_10_2025.sql | 18 ++++ src/main/resources/message_en.properties | 1 + src/main/resources/message_it.properties | 1 + 23 files changed, 167 insertions(+), 55 deletions(-) create mode 100644 src/main/resources/db/dump/update_system_email_template_of_application_rejected_16_10_2025.sql diff --git a/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java b/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java index 371437a6..813790f6 100644 --- a/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java +++ b/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java @@ -622,6 +622,7 @@ public class GepafinConstant { public static final String SUBJECT = "subject"; public static final List MANUAL_EMAIL_KEYS = Arrays.asList(SUBJECT, MESSAGE); public static final String INVALID_EMAIL_JSON = "invalid.email.json"; + public static final String MORE_FIELDS_REQUIRED_FOR_REJECTION="more.fields.required"; } diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java index 22f7731a..226dccb3 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java @@ -599,6 +599,8 @@ public class ApplicationAmendmentRequestDao { String body = emailContent.getBody(); response.setEmailTemplate(body); } + response.setAmendmentType(entity.getType()); + response.setAmendmentDocumentType(entity.getAmendmentDocumentType()); return response; } diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java index f5ba0615..66fda669 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java @@ -19,8 +19,10 @@ import net.gepafin.tendermanagement.web.rest.api.errors.Status; import org.apache.commons.lang3.StringUtils; import org.json.JSONObject; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; +import org.springframework.web.multipart.MultipartFile; import java.math.BigDecimal; import java.text.MessageFormat; @@ -146,6 +148,11 @@ public class ApplicationEvaluationDao { @Autowired private EmailDao emailDao; + @Autowired + private DocumentDao documentDao; + + @Value("${default.hub.uuid}") + private String defaultHubUuid; private ApplicationEvaluationEntity convertToEntity(UserEntity user, ApplicationEvaluationRequest req, Long assignedApplciationId) { @@ -182,7 +189,7 @@ public class ApplicationEvaluationDao { ApplicationEvaluationResponse response = new ApplicationEvaluationResponse(); populateBasicDetails(entity, response); - + ApplicationEntity applicationEntity=entity.getAssignedApplicationsEntity().getApplication(); CallEntity call = callRepository.findCallEntityByApplicationId(entity.getApplicationId()); List evaluationCriterias = evaluationCriteriaRepository .findByCallIdAndLookupDataTypeAndIsDeletedFalse(call.getId(), LookUpDataEntity.LookUpDataTypeEnum.EVALUATION_CRITERIA.getValue()); @@ -201,10 +208,39 @@ public class ApplicationEvaluationDao { List allDocs = prepareEvaluationDocumentBeanList(entity); setEvaluationDocResponse(response, allDocs); setApplicationDetails(response, entity); + setRejectedDocuments(applicationEntity, response); return response; } + private void setRejectedDocuments(ApplicationEntity applicationEntity, ApplicationEvaluationResponse response) { + List initialDocumentBeans = new ArrayList<>(); + String initialDocuments = applicationEntity.getRejectedDocument(); + + if (initialDocuments != null && !initialDocuments.trim().isEmpty()) { + // Split the comma-separated values and process them + List documentIds = Arrays.stream(initialDocuments.split(",")) + .map(String::trim) + .filter(id -> !id.isEmpty()) + .collect(Collectors.toList()); + + initialDocumentBeans.addAll( + documentIds.stream() + .map(id -> { + try { + return applicationAmendmentRequestDao.createDocumentResponseBean(id); // Convert to Long + } catch (NumberFormatException e) { + // Handle invalid document IDs gracefully + return null; + } + }) + .filter(Objects::nonNull) // Skip null responses + .collect(Collectors.toList()) + ); + } + response.setRejectedDocument(initialDocumentBeans); + } + private void setAmendmentDetails(ApplicationEvaluationEntity entity, ApplicationEvaluationResponse response) { List amendmentRequests=applicationAmendmentRequestRepository.findAllByApplicationEvaluationIdAndIsDeletedFalse(entity.getId()); List amendmentDocumentResponseBeans=new ArrayList<>(); @@ -653,7 +689,7 @@ public class ApplicationEvaluationDao { public ApplicationEvaluationResponse createOrUpdateApplicationEvaluation( UserEntity user, ApplicationEvaluationRequest req, - Long assignedApplicationId) { + Long assignedApplicationId, List rejectedDocuments) { log.info("Start createOrUpdateApplicationEvaluation: assignedApplicationId={}, userId={}", assignedApplicationId, user.getId()); Optional existingEntityOptional = @@ -741,7 +777,7 @@ public class ApplicationEvaluationDao { if (status != null) { AssignedApplicationsEntity assignedApplicationsEntity = assignedApplications.get(); - return updateApplicationEvaluationStatus(application, assignedApplicationsEntity, status); + return updateApplicationEvaluationStatus(application, assignedApplicationsEntity, status,rejectedDocuments,req); } else { return convertToResponse(entity); } @@ -1903,7 +1939,7 @@ public class ApplicationEvaluationDao { } public ApplicationEvaluationResponse updateApplicationEvaluationStatus(ApplicationEntity application, AssignedApplicationsEntity assignedApplicationsEntity, - ApplicationStatusForEvaluation newStatus) { + ApplicationStatusForEvaluation newStatus, List files,ApplicationEvaluationRequest applicationEvaluationRequest) { log.info("Starting updateApplicationEvaluationStatus for applicationId: {}, assignedApplicationId: {}, newStatus: {}", application.getId(), assignedApplicationsEntity.getId(), newStatus); @@ -1942,17 +1978,17 @@ public class ApplicationEvaluationDao { log.info("Application status updated to {} for applicationId: {}", newStatus, application.getId()); } -// if(newStatus.equals(ApplicationStatusForEvaluation.TECHNICAL_EVALUATION_REJECTED)) { -// application.setStatus(newStatus.getValue()); -// log.info("Application status updated to {} for applicationId: {}", newStatus, application.getId()); -// emailNotificationDao.sendMailForApplicationTechnicalEvaluationRejected(application,hub,existingEntity); -// application.setDateRejected(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); -// emailSendResponse = emailDao.buildEmailSendResponseFromRequest(request); -// responses = List.of(emailSendResponse); -// if (!Boolean.TRUE.equals(emailSendResponse.getIsEmailSend())) { -// saveEmailSendResponseToEvaluation(emailSendResponse, existingEntity); -// } -// } + if(newStatus.equals(ApplicationStatusForEvaluation.TECHNICAL_EVALUATION_REJECTED)) { + application.setStatus(newStatus.getValue()); + log.info("Application status updated to {} for applicationId: {}", newStatus, application.getId()); + emailNotificationDao.sendMailForApplicationTechnicalEvaluationRejected(application,hub,existingEntity); + application.setDateRejected(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); + emailSendResponse = emailDao.buildEmailSendResponseFromRequest(request); + responses = List.of(emailSendResponse); + if (!Boolean.TRUE.equals(emailSendResponse.getIsEmailSend())) { + saveEmailSendResponseToEvaluation(emailSendResponse, existingEntity); + } + } application = applicationRepository.save(application); ApplicationEvaluationEntity oldApplicationEvaluation = Utils.getClonedEntityForData(existingEntity); @@ -1997,10 +2033,28 @@ public class ApplicationEvaluationDao { notificationDao.sendNotificationToBeneficiary(application, NotificationTypeEnum.EVALUATION_RESULT); } if (Boolean.TRUE.equals(statusType.equals((ApplicationStatusTypeEnum.REJECTED.getValue())))) { + String tipoInammissibilita =null; + if(Boolean.TRUE.equals(hub.getUniqueUuid().equals(defaultHubUuid))) { + if (applicationEvaluationRequest.getMotivation() == null || applicationEvaluationRequest.getRejectedReason() == null) { + throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.MORE_FIELDS_REQUIRED_FOR_REJECTION)); + } + if (files != null) { + List documentResponseBeans = uploadRejectedDocument(user.getId(), files, application); + List rejectedDocumentIds = documentResponseBeans.stream() + .map(DocumentResponseBean::getId) + .collect(Collectors.toList()); + String rejectedDocumentId = rejectedDocumentIds.stream() + .map(String::valueOf) + .collect(Collectors.joining(",")); + application.setRejectedDocument(rejectedDocumentId); + } + tipoInammissibilita=applicationEvaluationRequest.getRejectedReason(); + application.setRejectedReason(applicationEvaluationRequest.getRejectedReason()); + } application.setDateRejected(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); application.setUpdatedDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); application = applicationRepository.save(application); - emailNotificationDao.sendInadmissibilityEmailForRejectedApplication(application,existingEntity); + emailNotificationDao.sendInadmissibilityEmailForRejectedApplication(application,existingEntity,tipoInammissibilita); emailSendResponse = emailDao.buildEmailSendResponseFromRequest(request); responses = List.of(emailSendResponse); if (!Boolean.TRUE.equals(emailSendResponse.getIsEmailSend())) { @@ -2083,7 +2137,7 @@ public class ApplicationEvaluationDao { return convertToResponse(savedEntity); } - public ApplicationEvaluationFormResponse createApplicationEvaluation(HttpServletRequest request, ApplicationEvaluationFormRequestBean applicationEvaluationFormRequestBean, Long evaluationFormId, Long assignedApplicationId){ + public ApplicationEvaluationFormResponse createApplicationEvaluation(HttpServletRequest request, List files, ApplicationEvaluationFormRequestBean applicationEvaluationFormRequestBean, Long evaluationFormId, Long assignedApplicationId){ log.info("Start createApplicationEvaluation - assignedApplicationId: {}, evaluationFormId: {}", assignedApplicationId, evaluationFormId); UserEntity user = validator.validateUser(request); @@ -2094,7 +2148,7 @@ public class ApplicationEvaluationDao { ApplicationEvaluationRequest req = convertToApplicationEvaluationRequest(applicationEvaluationFormRequestBean); // Call the existing method to create or update evaluation - ApplicationEvaluationResponse evaluationResponse = createOrUpdateApplicationEvaluation(user, req, assignedApplicationId); + ApplicationEvaluationResponse evaluationResponse = createOrUpdateApplicationEvaluation(user, req, assignedApplicationId,files); ApplicationEvaluationEntity entity = applicationEvaluationService.validateApplicationEvaluation(evaluationResponse.getId()); @@ -2415,7 +2469,7 @@ public class ApplicationEvaluationDao { request.setApplicationStatus(formRequestBean.getApplicationStatus()); request.setMotivation(formRequestBean.getMotivation()); request.setAmountAccepted(formRequestBean.getAmountAccepted()); - + request.setRejectedReason(formRequestBean.getRejectedReason()); request.setCriteria(null); request.setChecklist(null); @@ -2625,7 +2679,6 @@ public class ApplicationEvaluationDao { log.info("Application status updated to {} for applicationId: {}", ApplicationStatusForEvaluation.TECHNICAL_EVALUATION_REJECTED, application.getId()); emailNotificationDao.sendMailForApplicationTechnicalEvaluationRejected(application, hub, existingEntity); application.setDateRejected(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); - application.setEmailJson(Utils.convertMapIntoJsonString(applicationRequest.getEmailJson())); emailSendResponse = emailDao.buildEmailSendResponseFromRequest(request); responses = List.of(emailSendResponse); if (!Boolean.TRUE.equals(emailSendResponse.getIsEmailSend())) { @@ -2643,5 +2696,11 @@ public class ApplicationEvaluationDao { } return null; } + public List uploadRejectedDocument(Long userId,List files,ApplicationEntity application){ + if(files!=null) { + return documentDao.uploadFiles(userId, files, application.getId(), DocumentSourceTypeEnum.APPLICATION, DocumentTypeEnum.DOCUMENT); + } + return new ArrayList<>(); + } } diff --git a/src/main/java/net/gepafin/tendermanagement/dao/AssignedApplicationsDao.java b/src/main/java/net/gepafin/tendermanagement/dao/AssignedApplicationsDao.java index 0df566f5..1a3c2e05 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/AssignedApplicationsDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/AssignedApplicationsDao.java @@ -116,7 +116,7 @@ public class AssignedApplicationsDao { UserEntity user = userService.validateUser(userId); AssignedApplicationsEntity assignment = createAssignmentEntity(application, user.getId(), assignedByUser, assignedApplicationsRequest); - applicationEvaluationDao.createOrUpdateApplicationEvaluation(user, new ApplicationEvaluationRequest(), assignment.getId()); + applicationEvaluationDao.createOrUpdateApplicationEvaluation(user, new ApplicationEvaluationRequest(), assignment.getId(),null); AssignedApplicationsResponse assignApplicationToInstructorResponse = convertEntityToResponse(assignment); log.info("Application assigned succesfully {}", assignApplicationToInstructorResponse); return assignApplicationToInstructorResponse; diff --git a/src/main/java/net/gepafin/tendermanagement/dao/CommunicationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/CommunicationDao.java index 81960f9d..ef7619b2 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/CommunicationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/CommunicationDao.java @@ -12,7 +12,6 @@ import net.gepafin.tendermanagement.enums.DocumentTypeEnum; import net.gepafin.tendermanagement.enums.VersionActionTypeEnum; import net.gepafin.tendermanagement.model.request.CommunicationRequestBean; import net.gepafin.tendermanagement.model.request.VersionHistoryRequest; -import net.gepafin.tendermanagement.model.response.ApplicationAmendmentResponse; import net.gepafin.tendermanagement.model.response.CommunicationResponseBean; import net.gepafin.tendermanagement.model.response.DocumentResponseBean; import net.gepafin.tendermanagement.repositories.CommunicationRepository; @@ -117,7 +116,7 @@ public class CommunicationDao { return "Deleted Comment Successfully."; } - public ApplicationAmendmentResponse getAmendmentComments(Long amendmentId) { + public List getAmendmentComments(Long amendmentId) { ApplicationAmendmentRequestEntity amendmentData = applicationAmendmentRequestService.validateApplicationAmendmentRequest(amendmentId); List commentsList = communicationRepository.findByApplicationAmendmentRequestIdAndIsDeletedFalse(amendmentId); @@ -130,7 +129,7 @@ public class CommunicationDao { CommunicationResponseBean communicationResponseBean=convertToCommunicationResponseBean(communicationEntity,communicationDocumentBeans); communicationResponseBeans.add(communicationResponseBean); } - return new ApplicationAmendmentResponse(amendmentData, communicationResponseBeans); + return communicationResponseBeans; } public CommunicationResponseBean updateAmendmentComment(CommunicationRequestBean communicationRequestBean, Long amendmentId, Long commentId) { diff --git a/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java index cc676a7b..bc35b897 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java @@ -158,8 +158,15 @@ public class EmailNotificationDao { : new HashSet<>(documentIds); documentEntities=documentRepository.findAllByIdInAndIsDeletedFalse(setOfDocumentIds); } + if(Boolean.TRUE.equals(userEntity.getHub().getUniqueUuid().equals(defaultHubUuid)) && Boolean.TRUE.equals(systemEmailTemplateResponse.getEmailScenario().equals(EmailScenarioTypeEnum.APPLICATION_REJECTED))) { + List documentIds=applicationDao.validateDocumentIds(applicationEntity.getRejectedDocument()); + Set setOfDocumentIds = (documentIds == null) + ? Collections.emptySet() + : new HashSet<>(documentIds); + documentEntities=documentRepository.findAllByIdInAndIsDeletedFalse(setOfDocumentIds); + } - urls = documentEntities.stream() + urls = documentEntities.stream() .map(DocumentEntity::getFilePath) // or getUrl() .collect(Collectors.toList()); if(Boolean.FALSE.equals(urls.isEmpty())) { @@ -376,7 +383,7 @@ public class EmailNotificationDao { sendEmail(applicationEntity, SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum.ADMISSIBILITY_NOTIFICATION, bodyPlaceholders, null,null); } - public void sendInadmissibilityEmailForRejectedApplication(ApplicationEntity applicationEntity,ApplicationEvaluationEntity applicationEvaluationEntity) { + public void sendInadmissibilityEmailForRejectedApplication(ApplicationEntity applicationEntity,ApplicationEvaluationEntity applicationEvaluationEntity,String tipoInammissibilita) { Map bodyPlaceholders = new HashMap<>(); bodyPlaceholders.put("{{call_name}}", applicationEntity.getCall().getName()); String protocolNumber=applicationEntity.getProtocol().getExternalProtocolNumber(); @@ -390,8 +397,9 @@ public class EmailNotificationDao { } bodyPlaceholders.put("{{protocol_date}}", protocolDate); bodyPlaceholders.put("{{protocol_time}}", DateTimeUtil.parseLocalTimeToString(applicationEntity.getProtocol().getTime(), GepafinConstant.HH_MM_SS)); + HubEntity hubEntity = hubService.valdateHub(applicationEntity.getHubId()); + bodyPlaceholders.put("{{tipo_inammissibilita}}", tipoInammissibilita); bodyPlaceholders.put("{{form_text}}", applicationEvaluationEntity.getMotivation()); - sendEmail(applicationEntity, SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum.INADMISSIBILITY_TEMPLATE, bodyPlaceholders, null,null); } diff --git a/src/main/java/net/gepafin/tendermanagement/entities/ApplicationEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/ApplicationEntity.java index 11182c78..8b8c64d7 100644 --- a/src/main/java/net/gepafin/tendermanagement/entities/ApplicationEntity.java +++ b/src/main/java/net/gepafin/tendermanagement/entities/ApplicationEntity.java @@ -79,9 +79,12 @@ public class ApplicationEntity extends BaseEntity { @Column(name="VAT_NUMBER") private String vatNumber; - @Column(name = "EMAIL_JSON") - private String emailJson; - @Column(name = "PREVIOUS_STATUS") private String previousStatus; + + @Column(name = "REJECTED_REASON") + private String rejectedReason; + + @Column(name = "REJECTED_DOCUMENT") + private String rejectedDocument; } \ No newline at end of file diff --git a/src/main/java/net/gepafin/tendermanagement/model/request/ApplicationEvaluationFormRequestBean.java b/src/main/java/net/gepafin/tendermanagement/model/request/ApplicationEvaluationFormRequestBean.java index d2c0e2dc..5564f08b 100644 --- a/src/main/java/net/gepafin/tendermanagement/model/request/ApplicationEvaluationFormRequestBean.java +++ b/src/main/java/net/gepafin/tendermanagement/model/request/ApplicationEvaluationFormRequestBean.java @@ -16,4 +16,5 @@ public class ApplicationEvaluationFormRequestBean { private List formFields; private String motivation; private BigDecimal amountAccepted; + private String rejectedReason; } diff --git a/src/main/java/net/gepafin/tendermanagement/model/request/ApplicationEvaluationRequest.java b/src/main/java/net/gepafin/tendermanagement/model/request/ApplicationEvaluationRequest.java index bd63054c..e19358c9 100644 --- a/src/main/java/net/gepafin/tendermanagement/model/request/ApplicationEvaluationRequest.java +++ b/src/main/java/net/gepafin/tendermanagement/model/request/ApplicationEvaluationRequest.java @@ -17,4 +17,5 @@ public class ApplicationEvaluationRequest { private ApplicationStatusForEvaluation applicationStatus; private String motivation; private BigDecimal amountAccepted; + private String rejectedReason; } diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationAmendmentRequestResponse.java b/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationAmendmentRequestResponse.java index c1fda306..b0df6e1c 100644 --- a/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationAmendmentRequestResponse.java +++ b/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationAmendmentRequestResponse.java @@ -34,4 +34,6 @@ public class ApplicationAmendmentRequestResponse { private String emailTemplate; private List emailSendResponse; private List amendmentInitialDocuments; + private String amendmentType; + private String amendmentDocumentType; } diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationEvaluationResponse.java b/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationEvaluationResponse.java index 49f07c6f..296d7f6b 100644 --- a/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationEvaluationResponse.java +++ b/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationEvaluationResponse.java @@ -50,5 +50,6 @@ public class ApplicationEvaluationResponse { private String companyVatNumber; private String companyCodiceAteco; private List emailSendResponse; + private List rejectedDocument; } diff --git a/src/main/java/net/gepafin/tendermanagement/service/ApplicationEvaluationService.java b/src/main/java/net/gepafin/tendermanagement/service/ApplicationEvaluationService.java index 45851c4d..e8cfd308 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/ApplicationEvaluationService.java +++ b/src/main/java/net/gepafin/tendermanagement/service/ApplicationEvaluationService.java @@ -5,6 +5,7 @@ import net.gepafin.tendermanagement.entities.ApplicationEvaluationEntity; import net.gepafin.tendermanagement.enums.FormActionEnum; import net.gepafin.tendermanagement.model.request.*; import net.gepafin.tendermanagement.model.response.*; +import org.springframework.web.multipart.MultipartFile; import java.util.List; @@ -12,7 +13,7 @@ public interface ApplicationEvaluationService { ApplicationEvaluationResponse createOrUpdateApplicationEvaluation( HttpServletRequest request, ApplicationEvaluationRequest applicationEvaluationRequest, - Long assignedApplicationsId); + Long assignedApplicationsId, List rejectedDocuments); void deleteApplicationEvaluation(HttpServletRequest request,Long id); @@ -21,7 +22,7 @@ public interface ApplicationEvaluationService { ApplicationEvaluationEntity validateApplicationEvaluationByApplicationId(Long applicationId); - ApplicationEvaluationFormResponse createApplicationEvaluation(HttpServletRequest request, ApplicationEvaluationFormRequestBean applicationEvaluationFormRequestBean, Long evaluationId, Long evaluationFormId); + ApplicationEvaluationFormResponse createApplicationEvaluation(HttpServletRequest request, List rejectedDocuments, ApplicationEvaluationFormRequestBean applicationEvaluationFormRequestBean, Long evaluationId, Long evaluationFormId); ApplicationEvaluationFormResponse getApplicationEvaluationForm(HttpServletRequest request, Long applicationId, Long assignedApplicationId); diff --git a/src/main/java/net/gepafin/tendermanagement/service/CommunicationService.java b/src/main/java/net/gepafin/tendermanagement/service/CommunicationService.java index 00b997b6..ac25493d 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/CommunicationService.java +++ b/src/main/java/net/gepafin/tendermanagement/service/CommunicationService.java @@ -2,7 +2,6 @@ package net.gepafin.tendermanagement.service; import jakarta.servlet.http.HttpServletRequest; import net.gepafin.tendermanagement.model.request.CommunicationRequestBean; -import net.gepafin.tendermanagement.model.response.ApplicationAmendmentResponse; import net.gepafin.tendermanagement.model.response.CommunicationResponseBean; import org.springframework.web.multipart.MultipartFile; @@ -15,5 +14,5 @@ public interface CommunicationService { CommunicationResponseBean updateAmendmentComment(HttpServletRequest request,CommunicationRequestBean communicationRequestBean, Long amendmentId, Long commentId); - ApplicationAmendmentResponse getAmendmentComments(HttpServletRequest request,Long id); + List getAmendmentComments(HttpServletRequest request,Long id); } diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationEvaluationServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationEvaluationServiceImpl.java index 4033dd70..5d64f783 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationEvaluationServiceImpl.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationEvaluationServiceImpl.java @@ -22,6 +22,7 @@ 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; @@ -47,13 +48,13 @@ public class ApplicationEvaluationServiceImpl implements ApplicationEvaluationSe public ApplicationEvaluationResponse createOrUpdateApplicationEvaluation( HttpServletRequest request, ApplicationEvaluationRequest req, - Long assignedApplicationsId) { + Long assignedApplicationsId, List rejectedDocuments) { AssignedApplicationsEntity assignedApplication =assignedApplicationsService.validateAssignedApplication(assignedApplicationsId); UserEntity user = validator.validatePreInstructor(request, assignedApplication.getUserId()); - return applicationEvaluationDao.createOrUpdateApplicationEvaluation(user, req, assignedApplication.getId()); + return applicationEvaluationDao.createOrUpdateApplicationEvaluation(user, req, assignedApplication.getId(),rejectedDocuments); } @Override @@ -88,10 +89,10 @@ public class ApplicationEvaluationServiceImpl implements ApplicationEvaluationSe @Override @Transactional(rollbackFor = Exception.class) - public ApplicationEvaluationFormResponse createApplicationEvaluation(HttpServletRequest request, ApplicationEvaluationFormRequestBean applicationEvaluationFormRequestBean, Long assignedApplicationId, Long evaluationFormId) { + public ApplicationEvaluationFormResponse createApplicationEvaluation(HttpServletRequest request, List rejectedDocuments, ApplicationEvaluationFormRequestBean applicationEvaluationFormRequestBean, Long assignedApplicationId, Long evaluationFormId) { AssignedApplicationsEntity assignedApplicationsEntity = assignedApplicationsService.validateAssignedApplication(assignedApplicationId); validator.validatePreInstructor(request, assignedApplicationsEntity.getUserId()); - return applicationEvaluationDao.createApplicationEvaluation(request,applicationEvaluationFormRequestBean,evaluationFormId,assignedApplicationId); + return applicationEvaluationDao.createApplicationEvaluation(request,rejectedDocuments,applicationEvaluationFormRequestBean,evaluationFormId,assignedApplicationId); } @Override diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/CommunicationServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/CommunicationServiceImpl.java index e0f125ae..a1096feb 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/CommunicationServiceImpl.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/CommunicationServiceImpl.java @@ -5,7 +5,6 @@ import net.gepafin.tendermanagement.dao.ApplicationAmendmentRequestDao; import net.gepafin.tendermanagement.dao.CommunicationDao; import net.gepafin.tendermanagement.entities.ApplicationAmendmentRequestEntity; import net.gepafin.tendermanagement.model.request.CommunicationRequestBean; -import net.gepafin.tendermanagement.model.response.ApplicationAmendmentResponse; import net.gepafin.tendermanagement.model.response.CommunicationResponseBean; import net.gepafin.tendermanagement.service.CommunicationService; import net.gepafin.tendermanagement.util.Validator; @@ -66,7 +65,7 @@ public class CommunicationServiceImpl implements CommunicationService { @Override @Transactional(rollbackFor = Exception.class) - public ApplicationAmendmentResponse getAmendmentComments(HttpServletRequest request,Long id) { + public List getAmendmentComments(HttpServletRequest request,Long id) { ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity = applicationAmendmentRequestDao.validateApplicationAmendmentRequest(id); if (Boolean.FALSE.equals(validator.checkIsBeneficiary())) { validator.validatePreInstructor(request, applicationAmendmentRequestEntity.getApplicationEvaluationEntity().getUserId()); diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/ApplicationEvaluationApi.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/ApplicationEvaluationApi.java index b2ff117e..30e0750d 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/ApplicationEvaluationApi.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/ApplicationEvaluationApi.java @@ -15,6 +15,7 @@ import net.gepafin.tendermanagement.web.rest.api.errors.ErrorConstants; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; import java.util.List; @@ -28,11 +29,12 @@ public interface ApplicationEvaluationApi { @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { @ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) }) - @PutMapping(value = "/{assignedApplicationsId}", produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE) + @PutMapping(value = "/{assignedApplicationsId}", produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.MULTIPART_FORM_DATA_VALUE) ResponseEntity> createOrUpdateApplicationEvaluation( HttpServletRequest request, - @Parameter(description = "Assigned Application ID", required = true) @PathVariable("assignedApplicationsId") Long assignedApplicationsId, - @Parameter(description = "Application Evaluation Request Body", required = true) @Valid @RequestBody ApplicationEvaluationRequest evaluationRequest); + @Parameter(description = "Assigned Application ID", required = true) @PathVariable("assignedApplicationsId") Long assignedApplicationsId, @Parameter(description = "List of files to upload", required = false) + @RequestPart(required = false) List rejectedDocuments, + @Parameter(description = "Application Evaluation Request Body", required = true) @RequestPart ApplicationEvaluationRequest evaluationRequest); @Operation(summary = "API to get ApplicationEvaluation data for evaluation process", responses = { @@ -67,9 +69,10 @@ public interface ApplicationEvaluationApi { @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { @ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) }) @PutMapping(value = "/v2/assignedApplication/{id}", - produces = { "application/json" }) - ResponseEntity> createApplicationEvaluation(HttpServletRequest request, - @Valid @RequestBody ApplicationEvaluationFormRequestBean applicationEvaluationFormRequestBean, + produces = { "application/json" },consumes = MediaType.MULTIPART_FORM_DATA_VALUE) + ResponseEntity> createApplicationEvaluation(HttpServletRequest request, @Parameter(description = "List of files to upload", required = false) + @RequestPart(required = false) List rejectedDocuments, + @RequestPart ApplicationEvaluationFormRequestBean applicationEvaluationFormRequestBean, @Parameter(description = "Assigned Application ID", required = true) @PathVariable(value = "id", required = true) Long assignedApplicationId, @Parameter(description = "The evaluation form ID", required = true) @RequestParam("evaluationFormId") Long evaluationFormId); diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/CommunicationApi.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/CommunicationApi.java index 78ecf16e..6f9d9ddc 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/CommunicationApi.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/CommunicationApi.java @@ -7,7 +7,6 @@ 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.model.request.CommunicationRequestBean; -import net.gepafin.tendermanagement.model.response.ApplicationAmendmentResponse; import net.gepafin.tendermanagement.model.response.CommunicationResponseBean; import net.gepafin.tendermanagement.model.util.Response; import net.gepafin.tendermanagement.web.rest.api.errors.ErrorConstants; @@ -44,7 +43,7 @@ public interface CommunicationApi { @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = @ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE))) }) @GetMapping(value = "/{amendmentId}", produces = "application/json") - public ResponseEntity> getAmendmentComments(HttpServletRequest request,@PathVariable(value = "amendmentId") Long amendmentId); + public ResponseEntity>> getAmendmentComments(HttpServletRequest request,@PathVariable(value = "amendmentId") Long amendmentId); @Operation(summary = "Api to update communication comments", responses = { @ApiResponse(responseCode = "200", description = "OK"), @ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/ApplicationEvaluationApiController.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/ApplicationEvaluationApiController.java index 21739f40..11e1eb1c 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/ApplicationEvaluationApiController.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/ApplicationEvaluationApiController.java @@ -18,6 +18,7 @@ import org.springframework.http.HttpStatus; 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 java.util.List; @@ -34,7 +35,7 @@ public class ApplicationEvaluationApiController implements ApplicationEvaluation @Override public ResponseEntity> createOrUpdateApplicationEvaluation( HttpServletRequest request, - Long assignedApplicationsId, + Long assignedApplicationsId, List rejectedDocuments, ApplicationEvaluationRequest evaluationRequest) { /** This code is responsible for creating user action logs for the "Create or update Application Evaluation" operation. **/ @@ -43,7 +44,7 @@ public class ApplicationEvaluationApiController implements ApplicationEvaluation ApplicationEvaluationResponse response = applicationEvaluationService.createOrUpdateApplicationEvaluation( - request, evaluationRequest, assignedApplicationsId); + request, evaluationRequest, assignedApplicationsId,rejectedDocuments); return ResponseEntity.status(HttpStatus.CREATED) .body(new Response<>(response, Status.SUCCESS, Translator.toLocale(GepafinConstant.USER_REQUEST_COMPLETED))); @@ -82,13 +83,13 @@ public class ApplicationEvaluationApiController implements ApplicationEvaluation } @Override - public ResponseEntity> createApplicationEvaluation(HttpServletRequest request, ApplicationEvaluationFormRequestBean applicationEvaluationFormRequestBean, Long assignedApplicationId, Long evaluationFormId) { + public ResponseEntity> createApplicationEvaluation(HttpServletRequest request, List rejectedDocuments, ApplicationEvaluationFormRequestBean applicationEvaluationFormRequestBean, Long assignedApplicationId, Long evaluationFormId) { /** This code is responsible for creating user action logs for the "Create or update application evaluation form" operation. **/ loggingUtil.logUserAction( UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.UPDATE).actionContext(UserActionContextEnum.CREATE_UPDATE_APPLICATION_EVALUATION_FORM).build()); - ApplicationEvaluationFormResponse applicationEvaluationResponseBean = applicationEvaluationService.createApplicationEvaluation(request, applicationEvaluationFormRequestBean, assignedApplicationId, evaluationFormId); + ApplicationEvaluationFormResponse applicationEvaluationResponseBean = applicationEvaluationService.createApplicationEvaluation(request,rejectedDocuments, applicationEvaluationFormRequestBean, assignedApplicationId, evaluationFormId); return ResponseEntity.status(HttpStatus.CREATED) .body(new Response<>(applicationEvaluationResponseBean, Status.SUCCESS, Translator.toLocale(GepafinConstant.EVALUATION_CREATED_SUCCESSFULLY))); diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/CommunicationController.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/CommunicationController.java index 5473d560..83b83fb3 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/CommunicationController.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/CommunicationController.java @@ -7,7 +7,6 @@ import net.gepafin.tendermanagement.enums.UserActionContextEnum; import net.gepafin.tendermanagement.enums.UserActionLogsEnum; import net.gepafin.tendermanagement.model.request.CommunicationRequestBean; import net.gepafin.tendermanagement.model.request.UserActionRequest; -import net.gepafin.tendermanagement.model.response.ApplicationAmendmentResponse; import net.gepafin.tendermanagement.model.response.CommunicationResponseBean; import net.gepafin.tendermanagement.model.util.Response; import net.gepafin.tendermanagement.service.CommunicationService; @@ -45,12 +44,12 @@ public class CommunicationController implements CommunicationApi { .body(new Response<>(communicationResponseBean, Status.SUCCESS, Translator.toLocale(GepafinConstant.COMMUNICATION_ADDED_TO_AMENDMENT_REQUEST_SUCCESS))); } @Override - public ResponseEntity> getAmendmentComments(HttpServletRequest request,Long amendmentId) { + public ResponseEntity>> getAmendmentComments(HttpServletRequest request,Long amendmentId) { /** This code is responsible for creating user action logs for the "getting comment of amendment" operation. **/ loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.VIEW).actionContext(UserActionContextEnum.GET_AMENDMENT_COMMENT).build()); - ApplicationAmendmentResponse response = communicationService.getAmendmentComments(request,amendmentId); + List response = communicationService.getAmendmentComments(request,amendmentId); return ResponseEntity.ok(new Response<>(response, Status.SUCCESS, Translator.toLocale(GepafinConstant.AMENDMENT_FOUND_SUCCESS))); } @Override 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 12afc8f4..d06919f3 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 @@ -3074,4 +3074,17 @@ + + + + + + + + + + + + + diff --git a/src/main/resources/db/dump/update_system_email_template_of_application_rejected_16_10_2025.sql b/src/main/resources/db/dump/update_system_email_template_of_application_rejected_16_10_2025.sql new file mode 100644 index 00000000..fb8bd4a2 --- /dev/null +++ b/src/main/resources/db/dump/update_system_email_template_of_application_rejected_16_10_2025.sql @@ -0,0 +1,18 @@ +UPDATE gepafin_schema.system_email_template +SET html_content = ' + +
+

Buongiorno,

+

Si comunica che, in riferimento alla domanda a valere sul bando “{{call_name}}” di cui al + Protocollo n. {{protocol_number}} del {{protocol_date}} alle {{protocol_time}}, +

+

+ {{tipo_inammissibilita}}.

+

Le motivazioni sono le seguenti: {{form_text}}

+

Vi ricordiamo che i Beneficiari che hanno presentato richieste valutate non ammissibili entro 10 giorni dalla data di ricevimento della presente potranno finoltrare richiesta di chiarimenti e/o osservazioni alla scrivente Società ai sensi e per gli effetti dell’art.10 bis della L.241/1990 e s.m.i.

+

Distinti Saluti,

+

{{email_signature}}

+
+ + ' +WHERE "type" = 'INADMISSIBILITY_NOTIFICATION' and "email_scenario" = 'APPLICATION_REJECTED' and "system" = true; \ No newline at end of file diff --git a/src/main/resources/message_en.properties b/src/main/resources/message_en.properties index 4357cac5..c02deff6 100644 --- a/src/main/resources/message_en.properties +++ b/src/main/resources/message_en.properties @@ -415,5 +415,6 @@ end.date.greater.than.now=End date must be greater than the current date and tim pec.email.required=PEC email is required. application.technical.evaluation.rejected.success=Application changes to status application technical evaluation rejected successfully. invalid.email.json=Invalid email json. +more.fields.required=Subject, reason, and motivation are required when rejecting the application. diff --git a/src/main/resources/message_it.properties b/src/main/resources/message_it.properties index 8a027a3a..e18f529a 100644 --- a/src/main/resources/message_it.properties +++ b/src/main/resources/message_it.properties @@ -406,3 +406,4 @@ end.date.greater.than.now=La data di fine deve essere successiva alla data e all pec.email.required=Obbligatorio l'indirizzo e-mail PEC. application.technical.evaluation.rejected.success=Lo stato dell'applicazione cambia: valutazione tecnica dell'applicazione rifiutata con successo. invalid.email.json=Codice email json non valido. +more.fields.required=Per rifiutare la domanda sono richiesti oggetto, motivo e motivazione. From 6d41a044d091ee1f15d0056025ace54240cdf4b9 Mon Sep 17 00:00:00 2001 From: rajesh Date: Fri, 17 Oct 2025 15:04:55 +0530 Subject: [PATCH 51/75] Added field rejectedReasonSubject for application rejection --- .../dao/ApplicationAmendmentRequestDao.java | 4 ++-- .../dao/ApplicationEvaluationDao.java | 7 +++++-- .../dao/EmailNotificationDao.java | 21 ++++++++++--------- .../ApplicationEvaluationFormRequestBean.java | 2 ++ .../request/ApplicationEvaluationRequest.java | 1 + .../db/changelog/db.changelog-1.0.0.xml | 5 +++++ ...ate_of_application_rejected_17_10_2025.sql | 3 +++ 7 files changed, 29 insertions(+), 14 deletions(-) create mode 100644 src/main/resources/db/dump/update_system_email_template_of_application_rejected_17_10_2025.sql diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java index ed5f6362..3e6bf38d 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java @@ -597,9 +597,9 @@ public class ApplicationAmendmentRequestDao { Map bodyPlaceholders = emailNotificationDao.prepareEmailPlaceholders(applicationEntity, entity); EmailContentResponse emailContent =null; if(entity.getType()!=null && entity.getType().equals(ApplicationAmendmentRequestTypeEnum.SPECIAL.getValue())){ - emailContent=emailNotificationDao.prepareEmailContent(applicationEntity, SystemEmailTemplatesEntityTypeEnum.SPECIAL_APPLICATION_AMENDMENT_REQUESTED, hubEntity, bodyPlaceholders); + emailContent=emailNotificationDao.prepareEmailContent(applicationEntity, SystemEmailTemplatesEntityTypeEnum.SPECIAL_APPLICATION_AMENDMENT_REQUESTED, hubEntity, bodyPlaceholders,null); }else { - emailContent = emailNotificationDao.prepareEmailContent(applicationEntity, SystemEmailTemplatesEntityTypeEnum.DOCUMENTATION_INTEGRATION_REQUEST, hubEntity, bodyPlaceholders); + emailContent = emailNotificationDao.prepareEmailContent(applicationEntity, SystemEmailTemplatesEntityTypeEnum.DOCUMENTATION_INTEGRATION_REQUEST, hubEntity, bodyPlaceholders,null); } String body = emailContent.getBody(); response.setEmailTemplate(body); diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java index 66fda669..bbc2a5df 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java @@ -2034,8 +2034,9 @@ public class ApplicationEvaluationDao { } if (Boolean.TRUE.equals(statusType.equals((ApplicationStatusTypeEnum.REJECTED.getValue())))) { String tipoInammissibilita =null; + String emailType=null; if(Boolean.TRUE.equals(hub.getUniqueUuid().equals(defaultHubUuid))) { - if (applicationEvaluationRequest.getMotivation() == null || applicationEvaluationRequest.getRejectedReason() == null) { + if (applicationEvaluationRequest.getMotivation() == null || applicationEvaluationRequest.getRejectedReason() == null || applicationEvaluationRequest.getRejectedReasonSubject()==null) { throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.MORE_FIELDS_REQUIRED_FOR_REJECTION)); } if (files != null) { @@ -2049,12 +2050,13 @@ public class ApplicationEvaluationDao { application.setRejectedDocument(rejectedDocumentId); } tipoInammissibilita=applicationEvaluationRequest.getRejectedReason(); + emailType=applicationEvaluationRequest.getRejectedReasonSubject(); application.setRejectedReason(applicationEvaluationRequest.getRejectedReason()); } application.setDateRejected(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); application.setUpdatedDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); application = applicationRepository.save(application); - emailNotificationDao.sendInadmissibilityEmailForRejectedApplication(application,existingEntity,tipoInammissibilita); + emailNotificationDao.sendInadmissibilityEmailForRejectedApplication(application,existingEntity,tipoInammissibilita,emailType); emailSendResponse = emailDao.buildEmailSendResponseFromRequest(request); responses = List.of(emailSendResponse); if (!Boolean.TRUE.equals(emailSendResponse.getIsEmailSend())) { @@ -2470,6 +2472,7 @@ public class ApplicationEvaluationDao { request.setMotivation(formRequestBean.getMotivation()); request.setAmountAccepted(formRequestBean.getAmountAccepted()); request.setRejectedReason(formRequestBean.getRejectedReason()); + request.setRejectedReasonSubject(formRequestBean.getRejectedReasonSubject()); request.setCriteria(null); request.setChecklist(null); diff --git a/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java index bc35b897..87b23c05 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java @@ -98,13 +98,13 @@ public class EmailNotificationDao { private ApplicationDao applicationDao; public void sendEmail(ApplicationEntity applicationEntity, SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum templateType, Map bodyPlaceholders, - List additionalRecipients, Long amendmentId) { + List additionalRecipients, Long amendmentId,String emailType) { HubEntity hubEntity = hubService.valdateHub(applicationEntity.getHubId()); // String service = determineService(applicationEntity.getHubId()); // String legalMail = service.equals("Gepafin S.p.a.") ? "bandi.gepafin@legalmail.it" : "bandi.sviluppumbria@legalmail.it"; - EmailContentResponse emailContent = prepareEmailContent(applicationEntity, templateType, hubEntity, bodyPlaceholders); + EmailContentResponse emailContent = prepareEmailContent(applicationEntity, templateType, hubEntity, bodyPlaceholders,emailType); UserEntity userEntity = userService.validateUser(applicationEntity.getUserId()); sendEmails(applicationEntity, userEntity, additionalRecipients,amendmentId,emailContent.getSystemEmailTemplateResponse(),emailContent.getSubject(),emailContent.getBody()); } @@ -113,7 +113,7 @@ public class EmailNotificationDao { ApplicationEntity applicationEntity, SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum templateType, HubEntity hubEntity, - Map bodyPlaceholders + Map bodyPlaceholders,String emailType ) { SystemEmailTemplateResponse systemEmailTemplateResponse = systemEmailTemplatesService.retrieveTemplateByTypeAndCall(templateType, hubEntity, null); if(Boolean.TRUE.equals(templateType.equals(SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum.DOCUMENTATION_INTEGRATION_REQUEST)) && Boolean.TRUE.equals(validator.isProductionProfileActivated()) && applicationEntity.getCall().getId().equals(23l)) { @@ -124,6 +124,7 @@ public class EmailNotificationDao { subjectPlaceholders.put("{{call_name}}", applicationEntity.getCall().getName()); subjectPlaceholders.put("{{company_name}}", company.getCompanyName()); // bodyPlaceholders.put("{{legal_mail}}", legalMail); + subjectPlaceholders.put("{{email_type}}",emailType); String subject = Utils.replacePlaceholders(systemEmailTemplateResponse.getSubject(), subjectPlaceholders); String body = Utils.replacePlaceholders(systemEmailTemplateResponse.getHtmlContent(), bodyPlaceholders); @@ -270,7 +271,7 @@ public class EmailNotificationDao { ApplicationEntity applicationEntity = applicationService.validateApplication(applicationAmendmentRequestEntity.getApplicationId()); Map bodyPlaceholders = prepareEmailPlaceholders(applicationEntity, applicationAmendmentRequestEntity); sendEmail(applicationEntity, SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum.DOCUMENTATION_INTEGRATION_REQUEST, bodyPlaceholders, null, - applicationAmendmentRequestEntity.getId()); + applicationAmendmentRequestEntity.getId(),null); } public Map prepareEmailPlaceholders(ApplicationEntity applicationEntity, ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity){ Map bodyPlaceholders = new HashMap<>(); @@ -362,7 +363,7 @@ public class EmailNotificationDao { } bodyPlaceholders.put("{{date_time_emailSend}}", DateTimeUtil.formatLocalDateTime(lastReminderDateTime, GepafinConstant.DD_MM_YYYY)); - sendEmail(applicationEntity, SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum.INADMISSIBILITY_NOTIFICATION_DUE_TO_FAILURE, bodyPlaceholders, null,amendmentRequest.getId()); + sendEmail(applicationEntity, SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum.INADMISSIBILITY_NOTIFICATION_DUE_TO_FAILURE, bodyPlaceholders, null,amendmentRequest.getId(),null); } public void sendAdmissibilityNotificationEmailForAdmissibleApplication(ApplicationEntity applicationEntity) { @@ -380,10 +381,10 @@ public class EmailNotificationDao { bodyPlaceholders.put("{{protocol_date}}", protocolDate); bodyPlaceholders.put("{{protocol_time}}", DateTimeUtil.parseLocalTimeToString(applicationEntity.getProtocol().getTime(), GepafinConstant.HH_MM_SS)); - sendEmail(applicationEntity, SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum.ADMISSIBILITY_NOTIFICATION, bodyPlaceholders, null,null); + sendEmail(applicationEntity, SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum.ADMISSIBILITY_NOTIFICATION, bodyPlaceholders, null,null,null); } - public void sendInadmissibilityEmailForRejectedApplication(ApplicationEntity applicationEntity,ApplicationEvaluationEntity applicationEvaluationEntity,String tipoInammissibilita) { + public void sendInadmissibilityEmailForRejectedApplication(ApplicationEntity applicationEntity,ApplicationEvaluationEntity applicationEvaluationEntity,String tipoInammissibilita,String emailType) { Map bodyPlaceholders = new HashMap<>(); bodyPlaceholders.put("{{call_name}}", applicationEntity.getCall().getName()); String protocolNumber=applicationEntity.getProtocol().getExternalProtocolNumber(); @@ -400,7 +401,7 @@ public class EmailNotificationDao { HubEntity hubEntity = hubService.valdateHub(applicationEntity.getHubId()); bodyPlaceholders.put("{{tipo_inammissibilita}}", tipoInammissibilita); bodyPlaceholders.put("{{form_text}}", applicationEvaluationEntity.getMotivation()); - sendEmail(applicationEntity, SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum.INADMISSIBILITY_TEMPLATE, bodyPlaceholders, null,null); + sendEmail(applicationEntity, SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum.INADMISSIBILITY_TEMPLATE, bodyPlaceholders, null,null,emailType); } public void sendMail(Long hubId, String subject, String body, List recipientEmails, EmailLogRequest emailLogRequest) { @@ -442,7 +443,7 @@ public class EmailNotificationDao { Map bodyPlaceholders = prepareEmailPlaceholdersForTechnicalEvaluationRejected(applicationEntity,hub,applicationEvaluationEntity); sendEmail(applicationEntity, SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum.INADMISSIBILITY_NOTIFICATION_DUE_TO_TECHNICAL_EVALUATION_FAILURE, bodyPlaceholders, null, - null); + null,null); } // public void sendMailForApplicationTechnicalEvaluationRejected(ApplicationEntity applicationEntity,HubEntity hub,ApplicationEvaluationEntity applicationEvaluationEntity,Map emailJson) { @@ -491,6 +492,6 @@ public class EmailNotificationDao { Map bodyPlaceholders = prepareEmailPlaceholders(applicationEntity, applicationAmendmentRequestEntity); sendEmail(applicationEntity, SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum.SPECIAL_APPLICATION_AMENDMENT_REQUESTED, bodyPlaceholders, null, - applicationAmendmentRequestEntity.getId()); + applicationAmendmentRequestEntity.getId(),null); } } \ No newline at end of file diff --git a/src/main/java/net/gepafin/tendermanagement/model/request/ApplicationEvaluationFormRequestBean.java b/src/main/java/net/gepafin/tendermanagement/model/request/ApplicationEvaluationFormRequestBean.java index 5564f08b..6d526122 100644 --- a/src/main/java/net/gepafin/tendermanagement/model/request/ApplicationEvaluationFormRequestBean.java +++ b/src/main/java/net/gepafin/tendermanagement/model/request/ApplicationEvaluationFormRequestBean.java @@ -17,4 +17,6 @@ public class ApplicationEvaluationFormRequestBean { private String motivation; private BigDecimal amountAccepted; private String rejectedReason; + private String rejectedReasonSubject; + } diff --git a/src/main/java/net/gepafin/tendermanagement/model/request/ApplicationEvaluationRequest.java b/src/main/java/net/gepafin/tendermanagement/model/request/ApplicationEvaluationRequest.java index e19358c9..71405f74 100644 --- a/src/main/java/net/gepafin/tendermanagement/model/request/ApplicationEvaluationRequest.java +++ b/src/main/java/net/gepafin/tendermanagement/model/request/ApplicationEvaluationRequest.java @@ -18,4 +18,5 @@ public class ApplicationEvaluationRequest { private String motivation; private BigDecimal amountAccepted; private String rejectedReason; + private String rejectedReasonSubject; } 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 d06919f3..f9fecdf1 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 @@ -3087,4 +3087,9 @@ + + + + + diff --git a/src/main/resources/db/dump/update_system_email_template_of_application_rejected_17_10_2025.sql b/src/main/resources/db/dump/update_system_email_template_of_application_rejected_17_10_2025.sql new file mode 100644 index 00000000..a42ce4a8 --- /dev/null +++ b/src/main/resources/db/dump/update_system_email_template_of_application_rejected_17_10_2025.sql @@ -0,0 +1,3 @@ +UPDATE gepafin_schema.system_email_template +SET subject = 'BANDO {{call_name}} – {{email_type}} {{company_name}}' +WHERE "type" = 'INADMISSIBILITY_NOTIFICATION' and "email_scenario" = 'APPLICATION_REJECTED' and "system" = true; \ No newline at end of file From 80c7403b6480f7763ea9cee91a56ee2593641187 Mon Sep 17 00:00:00 2001 From: rajesh Date: Wed, 22 Oct 2025 15:08:09 +0530 Subject: [PATCH 52/75] Added signed document in evaluation response --- .../tendermanagement/dao/ApplicationDao.java | 2 +- .../dao/ApplicationEvaluationDao.java | 15 +++++++++++++++ .../ApplicationEvaluationFormResponse.java | 1 + .../response/ApplicationEvaluationResponse.java | 1 + .../ApplicationSignedDocumentRepository.java | 3 +++ 5 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java index 35cd54a5..787e0346 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java @@ -1417,7 +1417,7 @@ public class ApplicationDao { throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.S3_PATH_GENERATION_ERROR_MSG)); } } - private ApplicationSignedDocumentResponse convertApplicationSignedDocumentToApplicationSignedDocumentResponse( + public ApplicationSignedDocumentResponse convertApplicationSignedDocumentToApplicationSignedDocumentResponse( ApplicationSignedDocumentEntity applicationSignedDocument) { ApplicationSignedDocumentResponse applicationSignedDocumentResponse = new ApplicationSignedDocumentResponse(); applicationSignedDocumentResponse.setId(applicationSignedDocument.getId()); diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java index bbc2a5df..430e28da 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java @@ -154,6 +154,9 @@ public class ApplicationEvaluationDao { @Value("${default.hub.uuid}") private String defaultHubUuid; + @Autowired + private ApplicationSignedDocumentRepository applicationSignedDocumentRepository; + private ApplicationEvaluationEntity convertToEntity(UserEntity user, ApplicationEvaluationRequest req, Long assignedApplciationId) { ApplicationEvaluationEntity entity = new ApplicationEvaluationEntity(); @@ -1188,6 +1191,7 @@ public class ApplicationEvaluationDao { } ApplicationEvaluationEntity entity = entityOptional.get(); ApplicationEvaluationResponse applicationEvaluationResponse = convertToResponse(entity); + applicationEvaluationResponse.setSignedDocument(getApplicationSignedDocument(entity)); applicationEvaluationResponse.setEmailSendResponse(entity.getEmailSendResponse()); return applicationEvaluationResponse; } @@ -2417,6 +2421,7 @@ public class ApplicationEvaluationDao { } response.setCompanyVatNumber(company.getVatNumber()); response.setCompanyCodiceAteco(company.getCodiceAteco()); + response.setSignedDocument(getApplicationSignedDocument(evaluationEntity)); response.setEmailSendResponse(evaluationEntity.getEmailSendResponse()); return response; } @@ -2705,5 +2710,15 @@ public class ApplicationEvaluationDao { } return new ArrayList<>(); } + public ApplicationSignedDocumentResponse getApplicationSignedDocument(ApplicationEvaluationEntity evaluationEntity){ + ApplicationSignedDocumentEntity applicationSignedDocument = applicationSignedDocumentRepository + .findByApplicationIdAndStatus(evaluationEntity.getApplicationId(), ApplicationSignedDocumentStatusEnum.ACTIVE.getValue()); + if(applicationSignedDocument == null) { + log.warn("No active signed document found for applicationId: {}", evaluationEntity.getApplicationId()); + throw new ResourceNotFoundException(Status.NOT_FOUND, + Translator.toLocale(GepafinConstant.APPLICATION_SIGNED_DOCUMENT_NOT_FOUND)); + } + return applicationDao.convertApplicationSignedDocumentToApplicationSignedDocumentResponse(applicationSignedDocument); + } } diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationEvaluationFormResponse.java b/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationEvaluationFormResponse.java index 92f7933a..84cf4989 100644 --- a/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationEvaluationFormResponse.java +++ b/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationEvaluationFormResponse.java @@ -49,5 +49,6 @@ public class ApplicationEvaluationFormResponse { private String companyVatNumber; private String companyCodiceAteco; private List emailSendResponse; + private ApplicationSignedDocumentResponse signedDocument; } diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationEvaluationResponse.java b/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationEvaluationResponse.java index 296d7f6b..33b58062 100644 --- a/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationEvaluationResponse.java +++ b/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationEvaluationResponse.java @@ -51,5 +51,6 @@ public class ApplicationEvaluationResponse { private String companyCodiceAteco; private List emailSendResponse; private List rejectedDocument; + private ApplicationSignedDocumentResponse signedDocument; } diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationSignedDocumentRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationSignedDocumentRepository.java index b9d2bce3..4f66d578 100644 --- a/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationSignedDocumentRepository.java +++ b/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationSignedDocumentRepository.java @@ -21,4 +21,7 @@ public interface ApplicationSignedDocumentRepository extends JpaRepository findAllByIsStatus(@Param("status")String status); + + ApplicationSignedDocumentEntity findByIdAndStatus(Long id, String status); + } From 6166f92801cca3cb05932de18fa0698271d59bc6 Mon Sep 17 00:00:00 2001 From: rajesh Date: Thu, 23 Oct 2025 17:09:04 +0530 Subject: [PATCH 53/75] Updated document logic for special amendment --- .../dao/EmailNotificationDao.java | 9 +++++++-- .../tendermanagement/util/S3DocxProcessor.java | 4 +++- .../resources/db/changelog/db.changelog-1.0.0.xml | 3 +++ ..._document_for_special_amendment_23-10-2025.sql | 15 +++++++++++++++ 4 files changed, 28 insertions(+), 3 deletions(-) create mode 100644 src/main/resources/db/dump/update_document_for_special_amendment_23-10-2025.sql diff --git a/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java index 87b23c05..4cce5925 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java @@ -145,12 +145,17 @@ public class EmailNotificationDao { Map replacements=new HashMap<>(); List documentEntities=new ArrayList<>(); if(systemEmailTemplateResponse.getEmailScenario().equals(EmailScenarioTypeEnum.SPECIAL_APPLICATION_AMENDMENT_REQUESTED)) { + String amount=Utils.convertToItalianFormat(String.valueOf(applicationEntity.getAmountAccepted())); replacements = Map.of( "{call_name}", applicationEntity.getCall().getName(), - "{amount_accepted}", String.valueOf(applicationEntity.getAmountAccepted()), + "{amount_accepted}", amount, "{pec}", "bandi.gepafin@legalmail.it" ); - documentEntities=documentRepository.findBySourceInAndIsDeletedFalse(List.of(applicationAmendmentRequest.getAmendmentDocumentType(),"MODELLO_AUTOCERTIFICAZIONE","MODELLO_PRIVACY")); + if(Boolean.TRUE.equals(AmendmentDocumentTypeEnum.ALTRE_GARANZIE.getValue().equals(applicationAmendmentRequest.getAmendmentDocumentType()))){ + documentEntities=documentRepository.findBySourceInAndIsDeletedFalse(List.of(applicationAmendmentRequest.getAmendmentDocumentType(),"MODELLO_AUTOCERTIFICAZIONE","MODELLO_PRIVACY")); + }else { + documentEntities = documentRepository.findBySourceInAndIsDeletedFalse(List.of(applicationAmendmentRequest.getAmendmentDocumentType())); + } } if(Boolean.TRUE.equals(userEntity.getHub().getUniqueUuid().equals(defaultHubUuid)) && Boolean.TRUE.equals(systemEmailTemplateResponse.getEmailScenario().equals(EmailScenarioTypeEnum.APPLICATION_AMENDMENT_REQUESTED))) { List documentIds=applicationDao.validateDocumentIds(applicationAmendmentRequest.getAmendmentInitialDocument()); diff --git a/src/main/java/net/gepafin/tendermanagement/util/S3DocxProcessor.java b/src/main/java/net/gepafin/tendermanagement/util/S3DocxProcessor.java index 9175eec1..86037d8f 100644 --- a/src/main/java/net/gepafin/tendermanagement/util/S3DocxProcessor.java +++ b/src/main/java/net/gepafin/tendermanagement/util/S3DocxProcessor.java @@ -10,6 +10,8 @@ import org.slf4j.LoggerFactory; import java.io.*; import java.net.URI; +import java.net.URLDecoder; +import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; @@ -44,7 +46,7 @@ public class S3DocxProcessor { // Extract bucket & key from URL AmazonS3URI s3Uri = new AmazonS3URI(s3Url); String bucket = s3Uri.getBucket(); - String key = s3Uri.getKey(); + String key = URLDecoder.decode(s3Uri.getKey(), StandardCharsets.UTF_8); try (S3Object s3Object = s3Client.getObject(bucket, key); InputStream originalStream = new BufferedInputStream(s3Object.getObjectContent())) { byte[] updatedBytes=null; 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 f9fecdf1..0a514895 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 @@ -3092,4 +3092,7 @@ + + + diff --git a/src/main/resources/db/dump/update_document_for_special_amendment_23-10-2025.sql b/src/main/resources/db/dump/update_document_for_special_amendment_23-10-2025.sql new file mode 100644 index 00000000..2854120f --- /dev/null +++ b/src/main/resources/db/dump/update_document_for_special_amendment_23-10-2025.sql @@ -0,0 +1,15 @@ +UPDATE gepafin_schema."document" +SET file_name='lettera di accettazione esito delibera – 1.docx', file_path='https://mementoresources.s3.amazonaws.com/gepafin/staging/template/lettera%20di%20accettazione%20esito%20delibera%20%E2%80%93%201.docx' +WHERE "source"='NESSUNA_GARANZIA'; + +UPDATE gepafin_schema."document" +SET file_name='lettera di accettazione esito delibera – 2.docx', file_path='https://mementoresources.s3.amazonaws.com/gepafin/staging/template/lettera%20di%20accettazione%20esito%20delibera%20%E2%80%93%202.docx' +WHERE "source"='GARANZIA_MCC'; + +UPDATE gepafin_schema."document" +SET file_name='lettera di accettazione esito delibera – 3.docx', file_path='https://mementoresources.s3.amazonaws.com/gepafin/staging/template/lettera%20di%20accettazione%20esito%20delibera%20%E2%80%93%203.docx' +WHERE "source"='MCC_START_UP'; + +UPDATE gepafin_schema."document" +SET file_name='lettera di accettazione esito delibera – 4.docx', file_path='https://mementoresources.s3.amazonaws.com/gepafin/staging/template/lettera%20di%20accettazione%20esito%20delibera%20%E2%80%93%204.docx' +WHERE "source"='ALTRE_GARANZIE'; \ No newline at end of file From 80d142ba941c1e0697b1e7f4efa9a7251db43ac0 Mon Sep 17 00:00:00 2001 From: rajesh Date: Fri, 24 Oct 2025 13:39:14 +0530 Subject: [PATCH 54/75] Add beneficiary email while sending the mail --- .../dao/ApplicationAmendmentRequestDao.java | 7 ++++++- .../gepafin/tendermanagement/dao/ApplicationDao.java | 7 +++++++ .../tendermanagement/dao/EmailNotificationDao.java | 11 ++++++++++- .../tendermanagement/enums/RecipientTypeEnum.java | 3 ++- 4 files changed, 25 insertions(+), 3 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java index 3e6bf38d..e5dd6c4b 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java @@ -1846,7 +1846,12 @@ public class ApplicationAmendmentRequestDao { throw new CustomValidationException(Status.VALIDATION_ERROR,Translator.toLocale(GepafinConstant.INVALID_APPLICATION_STATUS)); } ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity = new ApplicationAmendmentRequestEntity(); - applicationAmendmentRequestEntity.setResponseDays(20l); + if(Boolean.TRUE.equals(applicationAmendmentRequest.getAmendmentDocumentType().equals(AmendmentDocumentTypeEnum.ALTRE_GARANZIE))) { + applicationAmendmentRequestEntity.setResponseDays(20l); + } + else { + applicationAmendmentRequestEntity.setResponseDays(10l); + } applicationAmendmentRequestEntity.setEndDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now()).plusDays(20)); applicationAmendmentRequestEntity.setIsEmail(Boolean.TRUE); applicationAmendmentRequestEntity.setIsNotification(Boolean.FALSE); diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java index 787e0346..d4000034 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java @@ -1235,6 +1235,7 @@ public class ApplicationDao { emailLogRequest.setRecipientType(RecipientTypeEnum.BENEFICIARY); if(Boolean.TRUE.equals(hub.getUniqueUuid().equals(defaultHubUuid))){ + emailLogRequest.setRecipientType(RecipientTypeEnum.APPLICATION_PEC); email=applicationEntity.getPecEmail(); }else { email = userEntity.getBeneficiary().getEmail(); @@ -1242,6 +1243,12 @@ public class ApplicationDao { emailLogRequest.setRecipientId(userEntity.getBeneficiary().getId()); } emailNotificationDao.sendMail(hub.getId(), subject, body, List.of(email),emailLogRequest); + if (Boolean.TRUE.equals(hub.getUniqueUuid().equals(defaultHubUuid)) && userEntity.getBeneficiary() != null) { + emailLogRequest.setRecipientType(RecipientTypeEnum.BENEFICIARY); + email = userEntity.getBeneficiary().getEmail(); + emailLogRequest.setRecipientId(userEntity.getBeneficiary().getId()); + emailNotificationDao.sendMail(hub.getId(), subject, body, List.of(email),emailLogRequest); + } List recipientEmails = new ArrayList<>(); // recipientEmails.add(email); String companyEmail = userWithCompany.getEmail(); diff --git a/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java index 4cce5925..08650fb7 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java @@ -221,16 +221,25 @@ public class EmailNotificationDao { if (userEntity.getBeneficiary().getEmail() != null) { String beneficiaryEmail = null; + RecipientTypeEnum recipientTypeEnum=RecipientTypeEnum.BENEFICIARY; if (Boolean.TRUE.equals(userEntity.getHub().getUniqueUuid().equals(defaultHubUuid))){ + recipientTypeEnum=RecipientTypeEnum.APPLICATION_PEC; beneficiaryEmail=applicationEntity.getPecEmail(); }else { beneficiaryEmail=userEntity.getBeneficiary().getEmail(); } - EmailLogRequest emailLogRequest = emailLogDao.createEmailLogRequest(systemEmailTemplateResponse.getEmailScenario(), RecipientTypeEnum.BENEFICIARY,userEntity.getBeneficiary().getId() , + EmailLogRequest emailLogRequest = emailLogDao.createEmailLogRequest(systemEmailTemplateResponse.getEmailScenario(), recipientTypeEnum,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 (Boolean.TRUE.equals(userEntity.getHub().getUniqueUuid().equals(defaultHubUuid)) && userEntity.getBeneficiary() != null) { + String beneficiaryEmail = userEntity.getBeneficiary().getEmail(); + 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){ String hubEmails = userEntity.getHub().getEmail(); String[] hubEmailArray = hubEmails.split(","); diff --git a/src/main/java/net/gepafin/tendermanagement/enums/RecipientTypeEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/RecipientTypeEnum.java index 8f656154..a5026e96 100644 --- a/src/main/java/net/gepafin/tendermanagement/enums/RecipientTypeEnum.java +++ b/src/main/java/net/gepafin/tendermanagement/enums/RecipientTypeEnum.java @@ -8,7 +8,8 @@ public enum RecipientTypeEnum { USER("USER"), COMPANY("COMPANY"), PROPERTIES("PROPERTIES"), - INSTRUCTOR("INSTRUCTOR"); + INSTRUCTOR("INSTRUCTOR"), + APPLICATION_PEC("APPLICATION_PEC"); private String value; From ab5d63f3690ad95d16481407cc47ebdec50fac31 Mon Sep 17 00:00:00 2001 From: rajesh Date: Fri, 24 Oct 2025 14:48:37 +0530 Subject: [PATCH 55/75] Updated code --- .../tendermanagement/dao/ApplicationAmendmentRequestDao.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java index e5dd6c4b..0a0dd23f 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java @@ -1852,7 +1852,7 @@ public class ApplicationAmendmentRequestDao { else { applicationAmendmentRequestEntity.setResponseDays(10l); } - applicationAmendmentRequestEntity.setEndDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now()).plusDays(20)); + applicationAmendmentRequestEntity.setEndDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now()).plusDays(applicationAmendmentRequestEntity.getResponseDays())); applicationAmendmentRequestEntity.setIsEmail(Boolean.TRUE); applicationAmendmentRequestEntity.setIsNotification(Boolean.FALSE); applicationAmendmentRequestEntity.setStartDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); From 99603cbabe868a574ad99eea5359eaf5dc1e548f Mon Sep 17 00:00:00 2001 From: rajesh Date: Fri, 24 Oct 2025 19:03:47 +0530 Subject: [PATCH 56/75] Updated placeholder in doc for special amendment --- .../tendermanagement/dao/EmailNotificationDao.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java index 08650fb7..1d7ebd86 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java @@ -146,10 +146,16 @@ public class EmailNotificationDao { List documentEntities=new ArrayList<>(); if(systemEmailTemplateResponse.getEmailScenario().equals(EmailScenarioTypeEnum.SPECIAL_APPLICATION_AMENDMENT_REQUESTED)) { String amount=Utils.convertToItalianFormat(String.valueOf(applicationEntity.getAmountAccepted())); + String protocolNumber=applicationEntity.getProtocol().getExternalProtocolNumber(); + if(protocolNumber==null){ + protocolNumber= String.valueOf(applicationEntity.getProtocol().getProtocolNumber()); + } replacements = Map.of( "{call_name}", applicationEntity.getCall().getName(), "{amount_accepted}", amount, - "{pec}", "bandi.gepafin@legalmail.it" + "{pec}", "bandi.gepafin@legalmail.it", + "{company_name}", company.getCompanyName(), + "{protocol_number}", protocolNumber ); if(Boolean.TRUE.equals(AmendmentDocumentTypeEnum.ALTRE_GARANZIE.getValue().equals(applicationAmendmentRequest.getAmendmentDocumentType()))){ documentEntities=documentRepository.findBySourceInAndIsDeletedFalse(List.of(applicationAmendmentRequest.getAmendmentDocumentType(),"MODELLO_AUTOCERTIFICAZIONE","MODELLO_PRIVACY")); From a0a31ca0cc6ad599a59c9298977d3185f4f7624f Mon Sep 17 00:00:00 2001 From: rajesh Date: Tue, 28 Oct 2025 17:07:15 +0530 Subject: [PATCH 57/75] Resolved conflict --- src/main/resources/db/changelog/db.changelog-1.0.0.xml | 5 +++++ 1 file changed, 5 insertions(+) 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 f9fecdf1..313a874b 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 @@ -3092,4 +3092,9 @@ + + + + + From 42ca415f43796f1d103661697774b0c887381575 Mon Sep 17 00:00:00 2001 From: rajesh Date: Tue, 28 Oct 2025 17:17:10 +0530 Subject: [PATCH 58/75] Done ticket GEPADINBE-6144 --- .../tendermanagement/dao/AppointmentDao.java | 132 +++++++++++++----- .../dao/CompanyDocumentDao.java | 3 +- .../ApplicationSignedDocumentEntity.java | 3 + .../service/AmazonS3Service.java | 1 + .../service/AppointmentService.java | 2 +- .../service/impl/AmazonS3ServiceImpl.java | 14 +- .../service/impl/AppointmentServiceImpl.java | 4 +- .../impl/CompanyDocumentServiceImpl.java | 3 +- .../web/rest/api/AppointmentApi.java | 7 +- .../rest/api/impl/AppointmentController.java | 4 +- 10 files changed, 123 insertions(+), 50 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/AppointmentDao.java b/src/main/java/net/gepafin/tendermanagement/dao/AppointmentDao.java index cbd2f300..5b6bf8c1 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/AppointmentDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/AppointmentDao.java @@ -33,7 +33,9 @@ import net.gepafin.tendermanagement.service.feignClient.AppointmentApiService; import net.gepafin.tendermanagement.service.impl.ApplicationEvaluationServiceImpl; import net.gepafin.tendermanagement.util.LoggingUtil; 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.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; @@ -141,6 +143,12 @@ public class AppointmentDao { @Autowired private NdganagRepository ndganagRepository; + @Autowired + private ApplicationSignedDocumentRepository applicationSignedDocumentRepository; + + @Autowired + private Validator validator; + private final Map executorMap = new ConcurrentHashMap<>(); @@ -1152,35 +1160,55 @@ public class AppointmentDao { return appointmentCreationRequest; } - public DocumentUploadResponse uploadDocumentToExternalSystem(Long documentId, UploadDocToExternalSystemRequest docToExternalSystemRequest) { + public DocumentUploadResponse uploadDocumentToExternalSystem(Long documentId,Boolean isSignedDocument, UploadDocToExternalSystemRequest docToExternalSystemRequest) { log.info("Initiating upload to external system for documentId: {}", documentId); // Check if the document is already being processed - DocumentEntity systemDoc = documentDao.validateDocument(documentId); - ApplicationEntity application = null; + DocumentEntity systemDoc =null; + ApplicationSignedDocumentEntity applicationSignedDocument =null; + if(isSignedDocument!=null && Boolean.TRUE.equals(isSignedDocument)) { - if (systemDoc != null) { - DocumentSourceTypeEnum sourceType = DocumentSourceTypeEnum.valueOf(systemDoc.getSource()); + //all flow in incomplete and testing for document for that unique id + applicationSignedDocument = applicationSignedDocumentRepository + .findByIdAndStatus(documentId, ApplicationSignedDocumentStatusEnum.ACTIVE.getValue()); + if(applicationSignedDocument == null) { + log.warn("No active signed document found for id: {}", documentId); + throw new ResourceNotFoundException(Status.NOT_FOUND, + Translator.toLocale(GepafinConstant.APPLICATION_SIGNED_DOCUMENT_NOT_FOUND)); + } + application=applicationDao.validateApplication(applicationSignedDocument.getApplication().getId()); +// if (Boolean.TRUE.equals(validator.isProductionProfileActivated()) && application.getCall().getId().equals(23l)) { + // TO UPLOAD SIGNED DOCUMENT TO COMPANY DOCUMENT FOR SPECIFIC CALL 23 IN GEPAFIN +//// MultipartFile file=amazonS3Service.getFileFromS3Path(); +// } + } + else { + systemDoc = documentDao.validateDocument(documentId); - switch (sourceType) { - case APPLICATION: - application = applicationDao.validateApplication(systemDoc.getSourceId()); - break; - case AMENDMENT: - ApplicationAmendmentRequestEntity applicationAmendmentEntity = applicationAmendmentRequestDao.validateApplicationAmendmentRequest(systemDoc.getSourceId()); - application = applicationDao.validateApplication(applicationAmendmentEntity.getApplicationId()); - break; - case EVALUATION: - ApplicationEvaluationEntity applicationEvaluationEntity = applicationEvaluationDao.validateApplicationEvaluation(systemDoc.getSourceId()); - application = applicationDao.validateApplication(applicationEvaluationEntity.getApplicationId()); - break; - case CALL: - break; + if (systemDoc != null) { + DocumentSourceTypeEnum sourceType = DocumentSourceTypeEnum.valueOf(systemDoc.getSource()); - default: - log.warn("Unhandled document source type: {}", sourceType); - break; + switch (sourceType) { + case APPLICATION: + application = applicationDao.validateApplication(systemDoc.getSourceId()); + break; + case AMENDMENT: + ApplicationAmendmentRequestEntity applicationAmendmentEntity = applicationAmendmentRequestDao.validateApplicationAmendmentRequest(systemDoc.getSourceId()); + application = applicationDao.validateApplication(applicationAmendmentEntity.getApplicationId()); + break; + case EVALUATION: + ApplicationEvaluationEntity applicationEvaluationEntity = applicationEvaluationDao.validateApplicationEvaluation(systemDoc.getSourceId()); + application = applicationDao.validateApplication(applicationEvaluationEntity.getApplicationId()); + break; + + case CALL: + break; + + default: + log.warn("Unhandled document source type: {}", sourceType); + break; + } } } @@ -1190,7 +1218,15 @@ public class AppointmentDao { // Authenticate the hub before proceeding HubEntity hub = hubRepository.findByHubId(hubId); authenticateAndSaveToken(hub, application); - if (systemDoc != null && systemDoc.getDocumentAttachmentId() != null) { + String documentAttachmentId=null; + if (applicationSignedDocument!=null){ + documentAttachmentId=applicationSignedDocument.getDocumentAttachmentId(); + } + if(systemDoc!=null) { + documentAttachmentId=systemDoc.getDocumentAttachmentId(); + } + + if (documentAttachmentId!=null) { // If the documentAttachmentId is already set, return the response log.info("Document already uploaded with documentAttachmentId: {}", systemDoc.getDocumentAttachmentId()); DocumentUploadResponse response = new DocumentUploadResponse(); @@ -1215,7 +1251,7 @@ public class AppointmentDao { threadLocalHubId.set(hubId); try { log.info("Starting async document upload for documentId: {}", documentId); - uploadDocumentToExternalSystemSync(documentId, docToExternalSystemRequest, finalApplication); + uploadDocumentToExternalSystemSync(documentId, docToExternalSystemRequest, finalApplication,isSignedDocument); } catch (Exception e) { log.error("Error in async document upload for documentId: {}", documentId, e); } finally { @@ -1231,10 +1267,21 @@ public class AppointmentDao { return null; } - private void uploadDocumentToExternalSystemSync(Long documentId, UploadDocToExternalSystemRequest docToExternalSystemRequest, ApplicationEntity application) { + private void uploadDocumentToExternalSystemSync(Long documentId, UploadDocToExternalSystemRequest docToExternalSystemRequest, ApplicationEntity application,Boolean isSignedDocument) { log.info("Starting sync document upload for documentId: {}", documentId); // Synchronous upload logic - DocumentEntity systemDoc = documentDao.validateDocument(documentId); + ApplicationSignedDocumentEntity applicationSignedDocument=null; + DocumentEntity systemDoc=null; + String oldUrl = null; + + if(Boolean.TRUE.equals(isSignedDocument)){ + applicationSignedDocument = applicationSignedDocumentRepository + .findByIdAndStatus(documentId, ApplicationSignedDocumentStatusEnum.ACTIVE.getValue()); + oldUrl=applicationSignedDocument.getFilePath(); + }else { + systemDoc = documentDao.validateDocument(documentId); + oldUrl=systemDoc.getFilePath(); + } Long hubId = threadLocalHubId.get(); HubEntity hub = hubRepository.findByHubId(hubId); @@ -1245,13 +1292,17 @@ public class AppointmentDao { } log.info("Got Document in system: {}", systemDoc); - String oldUrl = systemDoc.getFilePath(); String authorizationToken = getBearerToken(hub); try { File localFile = downloadFileFromS3(oldUrl); MultipartFile multipartFile = convertFileToMultipartFile(localFile); + // delete temp file + if (!localFile.delete()) { + log.warn("Failed to delete temp file: {}", localFile.getAbsolutePath()); + } + UploadDocToExternalSystemRequest externalSystemRequest = new UploadDocToExternalSystemRequest(); externalSystemRequest.setInput(getUploadDocumentInput(docToExternalSystemRequest)); @@ -1268,14 +1319,20 @@ public class AppointmentDao { } // Save the documentAttachmentId to the database - systemDoc.setDocumentAttachmentId(parsedResponse.getDocumentAttachmentId()); - documentRepository.save(systemDoc); + if(systemDoc!=null) { + systemDoc.setDocumentAttachmentId(parsedResponse.getDocumentAttachmentId()); + documentRepository.save(systemDoc); + } + if(applicationSignedDocument!=null){ + applicationSignedDocument.setDocumentAttachmentId(parsedResponse.getDocumentAttachmentId()); + applicationSignedDocumentRepository.save(applicationSignedDocument); + } log.info("Document uploaded successfully to external system: {}", parsedResponse); } catch (FeignException.Forbidden forbiddenException) { log.error("403 Forbidden from external system during upload for documentId: {}. Retrying with new token...", documentId); regenerateTokenAndSave(hub, application); - uploadDocumentToExternalSystemSync(documentId, docToExternalSystemRequest, application); + uploadDocumentToExternalSystemSync(documentId, docToExternalSystemRequest, application,isSignedDocument); } catch (Exception e) { log.error("Exception during document upload: {}", e.getMessage(), e); throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.EXTERNAL_DOCUMENT_UPLOAD_FAILURE_MSG)); @@ -1305,13 +1362,21 @@ public class AppointmentDao { } private File downloadFileFromS3(String fileUrl) throws Exception { - String key = amazonS3Service.extractS3KeyFromUrl(fileUrl); String fileName = extractFileName(key); String folderPath = key.substring(0, key.lastIndexOf("/")); - File localFile = new File(GepafinConstant.TEMP_FILE_PATH + fileName); + // Use OS-independent temp folder + String tempFolder = System.getProperty("java.io.tmpdir"); - try (InputStream s3Stream = amazonS3Service.getFile(folderPath, key); FileOutputStream outputStream = new FileOutputStream(localFile)) { + File tempDir = new File(tempFolder); + if (!tempDir.exists() && !tempDir.mkdirs()) { + throw new IOException("Failed to create temp folder: " + tempDir.getAbsolutePath()); + } + + File localFile = new File(tempDir, fileName); + + try (InputStream s3Stream = amazonS3Service.getFile(folderPath, key); + FileOutputStream outputStream = new FileOutputStream(localFile)) { s3Stream.transferTo(outputStream); } @@ -1319,6 +1384,7 @@ public class AppointmentDao { return localFile; } + private String extractFileName(String filePath) { String[] parts = filePath.split("/"); diff --git a/src/main/java/net/gepafin/tendermanagement/dao/CompanyDocumentDao.java b/src/main/java/net/gepafin/tendermanagement/dao/CompanyDocumentDao.java index 5c5fa136..2f25bd75 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/CompanyDocumentDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/CompanyDocumentDao.java @@ -91,11 +91,10 @@ public class CompanyDocumentDao { @Autowired private AmazonS3 amazonS3; - public List uploadFileForCompany(HttpServletRequest request, Long userId, List files, Long companyId, Long documentCategoryId, CompanyDocumentTypeEnum companyDocumentSourceTypeEnum, LocalDateTime expirationDate,String name){ + public List uploadFileForCompany(Long userId, List files, Long companyId, Long documentCategoryId, CompanyDocumentTypeEnum companyDocumentSourceTypeEnum, LocalDateTime expirationDate,String name){ log.info("Uploading files for company. userId={}, companyId={}, documentCategoryId={}", userId, companyId, documentCategoryId); DocumentCategoryEntity categoryEntity = categoryDao.validateCategory(documentCategoryId); - validator.validateUserWithCompany(request,companyId); UserWithCompanyEntity userWithCompanyEntity=companyService.getUserWithCompany(userId,companyId); LocalDateTime currentDate = LocalDateTime.now(); diff --git a/src/main/java/net/gepafin/tendermanagement/entities/ApplicationSignedDocumentEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/ApplicationSignedDocumentEntity.java index 3f50c14b..496414b6 100644 --- a/src/main/java/net/gepafin/tendermanagement/entities/ApplicationSignedDocumentEntity.java +++ b/src/main/java/net/gepafin/tendermanagement/entities/ApplicationSignedDocumentEntity.java @@ -29,4 +29,7 @@ public class ApplicationSignedDocumentEntity extends BaseEntity { @Column(name="FILE_HASH") private String fileHash; + + @Column(name="DOCUMENT_ATTACHMENT_ID") + private String documentAttachmentId; } diff --git a/src/main/java/net/gepafin/tendermanagement/service/AmazonS3Service.java b/src/main/java/net/gepafin/tendermanagement/service/AmazonS3Service.java index 9766d58c..27e96b62 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/AmazonS3Service.java +++ b/src/main/java/net/gepafin/tendermanagement/service/AmazonS3Service.java @@ -1,4 +1,5 @@ package net.gepafin.tendermanagement.service; +import com.amazonaws.services.s3.AmazonS3; import org.springframework.stereotype.Component; import org.springframework.web.multipart.MultipartFile; diff --git a/src/main/java/net/gepafin/tendermanagement/service/AppointmentService.java b/src/main/java/net/gepafin/tendermanagement/service/AppointmentService.java index e324804c..affbfcc0 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/AppointmentService.java +++ b/src/main/java/net/gepafin/tendermanagement/service/AppointmentService.java @@ -12,7 +12,7 @@ public interface AppointmentService { AppointmentCreationResponse createAppointmentForApplication(HttpServletRequest request, Long applicationId, CreateAppointmentRequest createAppointmentRequest); - DocumentUploadResponse uploadDocToExternalSystem(HttpServletRequest request, Long documentId, UploadDocToExternalSystemRequest docToExternalSystemRequest); + DocumentUploadResponse uploadDocToExternalSystem(HttpServletRequest request, Long documentId,Boolean isSignedDocument,UploadDocToExternalSystemRequest docToExternalSystemRequest); NdgResponse getNdgByVatNumber(HttpServletRequest request,String vatNumber); diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/AmazonS3ServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/AmazonS3ServiceImpl.java index 8f87e40c..924a9df9 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/AmazonS3ServiceImpl.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/AmazonS3ServiceImpl.java @@ -24,6 +24,7 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.core.env.Environment; +import org.springframework.mock.web.MockMultipartFile; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; @@ -138,10 +139,15 @@ public class AmazonS3ServiceImpl implements AmazonS3Service { @Override public UploadFileOnAmazonS3Response uploadFileOnAmazonS3(String s3Folder, MultipartFile file) { String extension = FilenameUtils.getExtension(file.getOriginalFilename()); - String originalFileName = org.springframework.util.StringUtils.cleanPath(file.getOriginalFilename()); - String firstNameContain = originalFileName.substring(0, originalFileName.lastIndexOf('.')); - firstNameContain = Utils.replaceSpacesWithUnderscores(firstNameContain); - firstNameContain += "_" + Utils.randomKey(7); + String originalFileName = org.springframework.util.StringUtils.cleanPath(file.getOriginalFilename()); + String firstNameContain = originalFileName.substring(0, originalFileName.lastIndexOf('.')); + firstNameContain = Utils.replaceSpacesWithUnderscores(firstNameContain); + if(extension.equals("p7m")){ + firstNameContain =Utils.randomKey(7)+"_"+firstNameContain; + + }else { + firstNameContain += "_" + Utils.randomKey(7); + } String fileName = (firstNameContain + "." + extension); try { String filepath = upload(fileName, s3Folder, file); diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/AppointmentServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/AppointmentServiceImpl.java index 6c49b214..d910f043 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/AppointmentServiceImpl.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/AppointmentServiceImpl.java @@ -35,9 +35,9 @@ public class AppointmentServiceImpl implements AppointmentService { } @Override - public DocumentUploadResponse uploadDocToExternalSystem(HttpServletRequest request, Long documentId, UploadDocToExternalSystemRequest docToExternalSystemRequest) { + public DocumentUploadResponse uploadDocToExternalSystem(HttpServletRequest request, Long documentId,Boolean isSignedDocument, UploadDocToExternalSystemRequest docToExternalSystemRequest) { - return appointmentDao.uploadDocumentToExternalSystem(documentId, docToExternalSystemRequest); + return appointmentDao.uploadDocumentToExternalSystem(documentId,isSignedDocument, docToExternalSystemRequest); } @Override diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/CompanyDocumentServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/CompanyDocumentServiceImpl.java index c12e1ab3..b76a82f0 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/CompanyDocumentServiceImpl.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/CompanyDocumentServiceImpl.java @@ -33,7 +33,8 @@ public class CompanyDocumentServiceImpl implements CompanyDocumentService { Map userInfo = validator.getUserInfoFromToken(request); Long userId = validator.getUserId(userInfo); files.forEach(Utils::validateFileType); - return companyDocumentDao.uploadFileForCompany(request,userId,files,companyId,documentCategoryId,documentSourceTypeEnum,expirationDate,name); + validator.validateUserWithCompany(request,companyId); + return companyDocumentDao.uploadFileForCompany(userId,files,companyId,documentCategoryId,documentSourceTypeEnum,expirationDate,name); } @Override diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/AppointmentApi.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/AppointmentApi.java index 64f767b9..0c639847 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/AppointmentApi.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/AppointmentApi.java @@ -15,10 +15,7 @@ import net.gepafin.tendermanagement.model.util.Response; import net.gepafin.tendermanagement.web.rest.api.errors.ErrorConstants; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.*; public interface AppointmentApi { @@ -54,7 +51,7 @@ public interface AppointmentApi { @ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) }) @PostMapping(value = "/document/{documentId}", produces = MediaType.APPLICATION_JSON_VALUE) ResponseEntity> uploadDocumentToExternalSystem(HttpServletRequest request, - @Parameter(description = "The document id", required = true) @PathVariable(value = "documentId", required = true) Long documentId, + @Parameter(description = "The document id", required = true) @PathVariable(value = "documentId", required = true) Long documentId,@RequestParam(value = "isSignedDocument", required = false) Boolean isSignedDocument, @RequestBody UploadDocToExternalSystemRequest docToExternalSystemRequest); @Operation(summary = "API to get ndg by vatNumber", responses = { @ApiResponse(responseCode = "200", description = "OK"), diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/AppointmentController.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/AppointmentController.java index 7212355a..6665e871 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/AppointmentController.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/AppointmentController.java @@ -65,14 +65,14 @@ public class AppointmentController implements AppointmentApi { } @Override - public ResponseEntity> uploadDocumentToExternalSystem(HttpServletRequest request, Long documentId, + public ResponseEntity> uploadDocumentToExternalSystem(HttpServletRequest request, Long documentId,Boolean isSignedDocument, UploadDocToExternalSystemRequest docToExternalSystemRequest) { /** This code is responsible for creating user action logs for the "Upload document to external system" operation. **/ loggingUtil.logUserAction( UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.UPLOAD).actionContext(UserActionContextEnum.UPLOAD_DOCUMENT_TO_EXTERNAL_SYSTEM).build()); - DocumentUploadResponse documentUploadResponse = appointmentService.uploadDocToExternalSystem(request, documentId, docToExternalSystemRequest); + DocumentUploadResponse documentUploadResponse = appointmentService.uploadDocToExternalSystem(request, documentId,isSignedDocument ,docToExternalSystemRequest); String message = GepafinConstant.DOCUMENT_UPLOADED_SUCCESSFULLY_TO_EXTERNAL_SYSTEM; if(documentUploadResponse == null) { From daa956a98ae11db280e2e79a016430599c3da47c Mon Sep 17 00:00:00 2001 From: rajesh Date: Wed, 29 Oct 2025 15:01:18 +0530 Subject: [PATCH 59/75] Done ticket GEPAFINBE-6145 --- .../tendermanagement/dao/DocumentDao.java | 27 ++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/DocumentDao.java b/src/main/java/net/gepafin/tendermanagement/dao/DocumentDao.java index 597e3c4f..5fdf7e99 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/DocumentDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/DocumentDao.java @@ -17,6 +17,7 @@ import net.gepafin.tendermanagement.repositories.*; import net.gepafin.tendermanagement.util.LoggingUtil; import net.gepafin.tendermanagement.util.Utils; import net.gepafin.tendermanagement.web.rest.api.errors.CustomValidationException; +import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.web.multipart.MultipartFile; @@ -251,7 +252,12 @@ public class DocumentDao { } else if (DocumentSourceTypeEnum.APPLICATION.getValue().equalsIgnoreCase(documentEntity.getSource())) { applicationId = documentEntity.getSourceId(); ApplicationEntity applicationEntity = applicationService.validateApplication(applicationId); - + String rejectedDocument=applicationEntity.getRejectedDocument(); + if(applicationEntity.getRejectedDocument()!=null) { + String updatedValue = removeDocumentIdFromFieldValue(rejectedDocument, documentId); + applicationEntity.setRejectedDocument(updatedValue); + applicationRepository.save(applicationEntity); + } List applicationFormEntity=applicationFormRepository.findByApplicationId(applicationId); for (ApplicationFormEntity applicationForm:applicationFormEntity){ FormEntity formEntity=applicationForm.getForm(); @@ -276,13 +282,17 @@ public class DocumentDao { amendmentId = documentEntity.getSourceId(); ApplicationEntity applicationEntity = applicationAmendmentRequestRepository.findApplicationByAmendmentId(amendmentId); Optional applicationAmendmentRequestEntity=applicationAmendmentRequestRepository.findByIdAndIsDeletedFalse(amendmentId); - Map amendmentFormFieldMap = Utils + Map amendmentFormFieldMap =null; + if(Boolean.FALSE.equals(StringUtils.isEmpty(applicationAmendmentRequestEntity.get().getFormFields()))){ + amendmentFormFieldMap = Utils .convertJsonStringToList(applicationAmendmentRequestEntity.get().getFormFields(), AmendmentFormField.class) .stream().collect(Collectors.toMap(AmendmentFormField::getFieldId, Function.identity())); for (Map.Entry entry : amendmentFormFieldMap.entrySet()) { AmendmentFormField amendmentFormField=entry.getValue(); String updatedValue = removeDocumentIdFromFieldValue(amendmentFormField.getFieldValue(), documentId); amendmentFormField.setFieldValue(updatedValue); + } + applicationAmendmentRequestEntity.get().setFormFields(Utils.convertListToJsonString(amendmentFormFieldMap.values().stream().toList())); } String amendmentDocs=applicationAmendmentRequestEntity.get().getAmendmentDocument(); Map amendmentDocument=Utils.convertIntoJson(amendmentDocs); @@ -297,7 +307,6 @@ public class DocumentDao { // Step 5: Set it back to entity applicationAmendmentRequestEntity.get().setAmendmentDocument(updatedAmendmentDocs); } - applicationAmendmentRequestEntity.get().setFormFields(Utils.convertListToJsonString(amendmentFormFieldMap.values().stream().toList())); applicationAmendmentRequestRepository.save(applicationAmendmentRequestEntity.get()); applicationId = applicationEntity.getId(); @@ -321,6 +330,18 @@ public class DocumentDao { callId = applicationEntity.getCall().getId(); log.info("Processing document of type EVALUATION. Resolved evaluationId={}, applicationId={}, callId={}", evaluationId, applicationId, callId); } + else if(DocumentSourceTypeEnum.COMMUNICATION.getValue().equalsIgnoreCase(documentEntity.getSource())) { + communicationId = documentEntity.getSourceId(); + Optional communicationEntity=communicationRepository.findByIdAndIsDeletedFalse(communicationId); + CommunicationEntity communicationEntity1=communicationEntity.get(); + String communicationDocuments=communicationEntity1.getDocuments(); + if(communicationEntity1.getDocuments()!=null) { + String updatedValue = removeDocumentIdFromFieldValue(communicationDocuments, documentId); + communicationEntity1.setDocuments(updatedValue); + communicationRepository.save(communicationEntity1); + } + + } deleteFileFromS3(documentEntity, callId, applicationId,amendmentId,communicationId); log.info("Successfully deleted file from S3 for documentId={}", documentId); } From 5171c69df437ed8d0a823d21180696ee52909795 Mon Sep 17 00:00:00 2001 From: rajesh Date: Tue, 4 Nov 2025 16:46:25 +0530 Subject: [PATCH 60/75] Done ticket GEPAFINBE-6143 --- .../constants/GepafinConstant.java | 9 +- .../dao/ApplicationAmendmentRequestDao.java | 2 +- .../dao/ApplicationContractDao.java | 220 ++++++++++++++++++ .../tendermanagement/dao/ApplicationDao.java | 46 +++- .../gepafin/tendermanagement/dao/CallDao.java | 2 +- .../dao/CompanyDocumentDao.java | 2 +- .../tendermanagement/dao/DelegationDao.java | 2 +- .../tendermanagement/dao/DocumentDao.java | 45 +++- .../dao/EmailNotificationDao.java | 46 +++- .../tendermanagement/dao/S3PathConfig.java | 13 +- .../entities/ApplicationContractEntity.java | 46 ++++ .../enums/ApplicationContractStatusEnum.java | 22 ++ .../enums/ApplicationStatusTypeEnum.java | 4 +- .../enums/DocumentSourceTypeEnum.java | 3 +- .../enums/EmailScenarioTypeEnum.java | 3 +- .../enums/NotificationTypeEnum.java | 3 +- .../enums/UserActionContextEnum.java | 8 +- .../request/ApplicationContractRequest.java | 10 + .../response/ApplicationContractResponse.java | 30 +++ .../ApplicationContractRepository.java | 18 ++ .../service/ApplicationContractService.java | 21 ++ .../impl/ApplicationContractServiceImpl.java | 68 ++++++ .../impl/S3ReUploadMigrationService.java | 19 +- .../UserSignedAndDelegationServiceImpl.java | 2 +- .../web/rest/api/ApplicationContractApi.java | 96 ++++++++ .../ApplicationContractApiController.java | 86 +++++++ .../db/changelog/db.changelog-1.0.0.xml | 35 +++ ...ification_template_for_contract_upload.sql | 2 + src/main/resources/message_en.properties | 10 +- src/main/resources/message_it.properties | 8 + 30 files changed, 837 insertions(+), 44 deletions(-) create mode 100644 src/main/java/net/gepafin/tendermanagement/dao/ApplicationContractDao.java create mode 100644 src/main/java/net/gepafin/tendermanagement/entities/ApplicationContractEntity.java create mode 100644 src/main/java/net/gepafin/tendermanagement/enums/ApplicationContractStatusEnum.java create mode 100644 src/main/java/net/gepafin/tendermanagement/model/request/ApplicationContractRequest.java create mode 100644 src/main/java/net/gepafin/tendermanagement/model/response/ApplicationContractResponse.java create mode 100644 src/main/java/net/gepafin/tendermanagement/repositories/ApplicationContractRepository.java create mode 100644 src/main/java/net/gepafin/tendermanagement/service/ApplicationContractService.java create mode 100644 src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationContractServiceImpl.java create mode 100644 src/main/java/net/gepafin/tendermanagement/web/rest/api/ApplicationContractApi.java create mode 100644 src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/ApplicationContractApiController.java create mode 100644 src/main/resources/db/dump/insert_notification_template_for_contract_upload.sql diff --git a/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java b/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java index 813790f6..bf25387c 100644 --- a/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java +++ b/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java @@ -623,7 +623,14 @@ public class GepafinConstant { public static final List MANUAL_EMAIL_KEYS = Arrays.asList(SUBJECT, MESSAGE); public static final String INVALID_EMAIL_JSON = "invalid.email.json"; public static final String MORE_FIELDS_REQUIRED_FOR_REJECTION="more.fields.required"; - + public static final String CREATE_APPLICATION_CONTRACT="create.application.contract"; + public static final String APPLICATION_CONTRACT_NOT_FOUND="application.contract.not.found"; + public static final String APPLICATION_CONTRACT_FETCHED="application.contract.fetched"; + public static final String APPLICATION_CONTRACT_UPDATED="application.contract.updated"; + public static final String FILES_REQUIRED_FOR_CONTRACT="files.required.for.contract"; + public static final String APPLICATION_CONTRACT_ALREADY_EXIST="application.contract.already.exist"; + public static final String APPLICATION_NOT_APPROVED="application.not.approved"; + public static final String SUBJECT_AND_BODY_REQUIRED="subject.body.required"; } diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java index 0a0dd23f..73dc49ad 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java @@ -662,7 +662,7 @@ public class ApplicationAmendmentRequestDao { response.setApplicationFormFields(fileDetails); } - private List getDocumentResponseBean(String documentId) { + public List getDocumentResponseBean(String documentId) { List documentIds = extractIds(documentId); List documentResponseBeans = documentIds.stream() .map(id -> { diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationContractDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationContractDao.java new file mode 100644 index 00000000..e8e0a44d --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationContractDao.java @@ -0,0 +1,220 @@ +package net.gepafin.tendermanagement.dao; + +import jakarta.servlet.http.HttpServletRequest; +import net.gepafin.tendermanagement.config.Translator; +import net.gepafin.tendermanagement.constants.GepafinConstant; +import net.gepafin.tendermanagement.entities.ApplicationContractEntity; +import net.gepafin.tendermanagement.entities.ApplicationEntity; +import net.gepafin.tendermanagement.entities.ApplicationEvaluationEntity; +import net.gepafin.tendermanagement.entities.UserEntity; +import net.gepafin.tendermanagement.enums.*; +import net.gepafin.tendermanagement.model.request.ApplicationContractRequest; +import net.gepafin.tendermanagement.model.request.VersionHistoryRequest; +import net.gepafin.tendermanagement.model.response.ApplicationContractResponse; +import net.gepafin.tendermanagement.model.response.DocumentResponseBean; +import net.gepafin.tendermanagement.repositories.ApplicationContractRepository; +import net.gepafin.tendermanagement.repositories.ApplicationRepository; +import net.gepafin.tendermanagement.util.DateTimeUtil; +import net.gepafin.tendermanagement.util.LoggingUtil; +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.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.web.multipart.MultipartFile; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +@Component +public class ApplicationContractDao { + + @Autowired + private ApplicationDao applicationDao; + + @Autowired + private DocumentDao documentDao; + + @Autowired + private ApplicationContractRepository applicationContractRepository; + + @Autowired + private ApplicationRepository applicationRepository; + + @Autowired + private HttpServletRequest request; + + @Autowired + private LoggingUtil loggingUtil; + + @Autowired + private ApplicationAmendmentRequestDao applicationAmendmentRequestDao; + + @Autowired + private EmailNotificationDao emailNotificationDao; + + @Autowired + private ApplicationEvaluationDao applicationEvaluationDao; + + @Autowired + private NotificationDao notificationDao; + + public ApplicationContractResponse createApplicationContract(Long applicationId, List contractDocuments, ApplicationContractRequest applicationContractRequest, UserEntity user) { + ApplicationEntity applicationEntity = applicationDao.validateApplication(applicationId); + + if (Boolean.FALSE.equals(applicationEntity.getStatus().equals(ApplicationStatusTypeEnum.APPROVED.getValue()))) { + throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.APPLICATION_NOT_APPROVED)); + } + if (applicationContractRequest.getSubject() == null || applicationContractRequest.getText() == null) { + throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.SUBJECT_AND_BODY_REQUIRED)); + } + ApplicationEntity oldApplicationData = Utils.getClonedEntityForData(applicationEntity); + ApplicationContractEntity existingApplicationContractEntity = applicationContractRepository.findByApplicationIdAndIsDeletedFalse(applicationId); + if (existingApplicationContractEntity != null) { + throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.APPLICATION_CONTRACT_ALREADY_EXIST)); + } + ApplicationContractEntity applicationContractEntity = createApplicationContractEntity(applicationContractRequest, user, applicationEntity); + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.INSERT).oldData(null).newData(applicationContractEntity).build()); + List documentResponseBeans = setContractDocuments(contractDocuments, user, applicationContractEntity); + applicationEntity.setStatus(ApplicationStatusTypeEnum.AWAITING_CONTRACT.getValue()); + applicationRepository.save(applicationEntity); + loggingUtil.addVersionHistory( + VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplicationData).newData(applicationEntity).build()); + emailNotificationDao.sendEmailForApplicationContracted(applicationEntity, applicationContractEntity, user); + return createApplicationContractResponse(applicationContractEntity, documentResponseBeans, null); + } + + private ApplicationContractResponse createApplicationContractResponse(ApplicationContractEntity applicationContractEntity, List instructorDocuments, List beneficiaryDocuments) { + ApplicationContractResponse applicationContractResponse = new ApplicationContractResponse(); + applicationContractResponse.setId(applicationContractEntity.getId()); + applicationContractResponse.setText(applicationContractEntity.getText()); + applicationContractResponse.setSubject(applicationContractEntity.getSubject()); + applicationContractResponse.setInstructorId(applicationContractEntity.getInstructorId()); + applicationContractResponse.setStatus(ApplicationContractStatusEnum.valueOf(applicationContractEntity.getStatus())); + applicationContractResponse.setInstructorDocuments(instructorDocuments); + applicationContractResponse.setBeneficiaryDocuments(beneficiaryDocuments); + applicationContractResponse.setCompletionDate(applicationContractEntity.getCompletionDate()); + applicationContractResponse.setBeneficiaryUserId(applicationContractEntity.getBeneficiaryUserId()); + return applicationContractResponse; + } + + private List setContractDocuments(List contractDocuments, UserEntity user, ApplicationContractEntity applicationContractEntity) { + List documentResponseBeans = uploadContractDocument(user.getId(), contractDocuments, applicationContractEntity.getId()); + List contractDocumentIds = documentResponseBeans.stream() + .map(DocumentResponseBean::getId) + .collect(Collectors.toList()); + String contractDocumentId = contractDocumentIds.stream() + .map(String::valueOf) + .collect(Collectors.joining(",")); + applicationContractEntity.setInstructorDocument(contractDocumentId); + applicationContractRepository.save(applicationContractEntity); + return documentResponseBeans; + } + + private ApplicationContractEntity createApplicationContractEntity(ApplicationContractRequest applicationContractRequest, UserEntity user, ApplicationEntity applicationEntity) { + ApplicationContractEntity applicationContractEntity = new ApplicationContractEntity(); + applicationContractEntity.setSubject(applicationContractRequest.getSubject()); + applicationContractEntity.setText(applicationContractRequest.getText()); + applicationContractEntity.setApplicationId(applicationEntity.getId()); + applicationContractEntity.setInstructorId(user.getId()); + applicationContractEntity.setIsDeleted(Boolean.FALSE); + applicationContractEntity.setApplicationId(applicationEntity.getId()); + applicationContractEntity.setStatus(ApplicationContractStatusEnum.DRAFT.getValue()); + applicationContractEntity.setBeneficiaryUserId(applicationEntity.getUserId()); + applicationContractRepository.save(applicationContractEntity); + return applicationContractEntity; + } + + public List uploadContractDocument(Long userId, List files, Long applicationContractId) { + if (files != null) { + return documentDao.uploadFiles(userId, files, applicationContractId, DocumentSourceTypeEnum.CONTRACT, DocumentTypeEnum.DOCUMENT); + } + return new ArrayList<>(); + } + + public ApplicationContractResponse updateApplicationContract(Long applicationContractId, List beneficiaryContractDocuments, UserEntity user) { + ApplicationContractEntity applicationContractEntity = validateApplicationContract(applicationContractId); + ApplicationContractEntity oldApplicationContract = Utils.getClonedEntityForData(applicationContractEntity); + applicationContractEntity.setCompletionDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); + applicationContractEntity.setStatus(ApplicationContractStatusEnum.SIGNED.getValue()); + List beneficiaryContractDocuments1 = setBeneficiaryContractDocuments(beneficiaryContractDocuments, user, applicationContractEntity); + List documentResponseBeans = applicationAmendmentRequestDao.getDocumentResponseBean(applicationContractEntity.getInstructorDocument()); + loggingUtil.addVersionHistory( + VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplicationContract).newData(applicationContractEntity).build()); + ApplicationEntity applicationEntity = applicationDao.validateApplication(applicationContractEntity.getApplicationId()); + ApplicationEntity oldApplicationData = Utils.getClonedEntityForData(applicationEntity); + ApplicationEvaluationEntity applicationEvaluationEntity = applicationEvaluationDao.validateApplicationEvaluation(applicationEntity.getApplicationEvaluationId()); + applicationEntity.setStatus(ApplicationStatusTypeEnum.CONTRACT_SIGNED.getValue()); + applicationRepository.save(applicationEntity); + loggingUtil.addVersionHistory( + VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplicationData).newData(applicationEntity).build()); + Map placeHolders = new HashMap<>(); + placeHolders.put("{{call_name}}", applicationEntity.getCall().getName()); + String protocolNumber = applicationEntity.getProtocol().getExternalProtocolNumber(); + if (protocolNumber == null) { + protocolNumber = String.valueOf(applicationEntity.getProtocol().getProtocolNumber()); + } + placeHolders.put("{{protocol_number}}", protocolNumber); + notificationDao.sendNotificationToInstructor(placeHolders, applicationEvaluationEntity, NotificationTypeEnum.CONTRACT_UPLOAD); + + return createApplicationContractResponse(applicationContractEntity, documentResponseBeans, beneficiaryContractDocuments1); + } + + public ApplicationContractEntity validateApplicationContract(Long applicationContractId) { + ApplicationContractEntity applicationContractEntity = applicationContractRepository.findByIdAndIsDeletedFalse(applicationContractId); + if (applicationContractEntity == null) { + throw new CustomValidationException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.APPLICATION_CONTRACT_NOT_FOUND)); + } + return applicationContractEntity; + } + + private List setBeneficiaryContractDocuments(List contractDocuments, UserEntity user, ApplicationContractEntity applicationContractEntity) { + List documentResponseBeans = uploadContractDocument(user.getId(), contractDocuments, applicationContractEntity.getId()); + List contractDocumentIds = documentResponseBeans.stream() + .map(DocumentResponseBean::getId) + .collect(Collectors.toList()); + String contractDocumentId = contractDocumentIds.stream() + .map(String::valueOf) + .collect(Collectors.joining(",")); + applicationContractEntity.setBeneficiaryDocument(contractDocumentId); + applicationContractRepository.save(applicationContractEntity); + return documentResponseBeans; + } + + public ApplicationContractResponse getContractById(Long contractId) { + ApplicationContractEntity applicationContractEntity = validateApplicationContract(contractId); + return createApplicationContractResponseFromEntity(applicationContractEntity); + } + + private ApplicationContractResponse createApplicationContractResponseFromEntity(ApplicationContractEntity applicationContractEntity) { + List instructorDocuments = applicationAmendmentRequestDao.getDocumentResponseBean(applicationContractEntity.getInstructorDocument()); + List beneficiaryDocuments = applicationAmendmentRequestDao.getDocumentResponseBean(applicationContractEntity.getBeneficiaryDocument()); + return createApplicationContractResponse(applicationContractEntity, instructorDocuments, beneficiaryDocuments); + } + + public ApplicationContractResponse getContractByApplicationId(Long applicationId) { + ApplicationContractEntity applicationContractEntity = applicationContractRepository.findByApplicationIdAndIsDeletedFalse(applicationId); + if (applicationContractEntity == null) { + return null; + } + return createApplicationContractResponseFromEntity(applicationContractEntity); + } + + public List getContractByBeneficiaryUserId(UserEntity user) { + + List applicationContractEntities = applicationContractRepository.findByBeneficiaryUserIdAndStatusAndIsDeletedFalse(user.getId(), ApplicationContractStatusEnum.DRAFT.getValue()); + if (applicationContractEntities.isEmpty()) { + return null; + } + List applicationContractResponses = new ArrayList<>(); + for (ApplicationContractEntity applicationContractEntity : applicationContractEntities) { + ApplicationContractResponse applicationContractResponse = createApplicationContractResponseFromEntity(applicationContractEntity); + applicationContractResponses.add(applicationContractResponse); + } + return applicationContractResponses; + } +} diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java index d4000034..56e267be 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java @@ -229,6 +229,9 @@ public class ApplicationDao { @Autowired private SystemEmailTemplatesDao systemEmailTemplatesDao; + @Autowired + private ApplicationContractRepository applicationContractRepository; + public final Random random = new Random(); public ApplicationResponseBean createApplication(HttpServletRequest request, ApplicationRequestBean applicationRequestBean, Long formId, Long applicationId) { @@ -1383,7 +1386,7 @@ public class ApplicationDao { ApplicationSignedDocumentEntity oldApplicationSignedDocument = Utils.getClonedEntityForData(applicationSignedDocumentEntity); String oldS3Path = applicationSignedDocumentEntity.getFilePath(); log.debug("Old S3 path: {} ", oldS3Path); - String newS3Path = s3ConfigBean.generateDocumentPathForOther(DocOtherSourceTypeEnum.DELETED_USER_SIGNED_DOCUMENT,applicationSignedDocumentEntity.getApplication().getCall().getId(),applicationSignedDocumentEntity.getApplication().getId(),0L,0L); + String newS3Path = s3ConfigBean.generateDocumentPathForOther(DocOtherSourceTypeEnum.DELETED_USER_SIGNED_DOCUMENT,applicationSignedDocumentEntity.getApplication().getCall().getId(),applicationSignedDocumentEntity.getApplication().getId(),0L,0L,0l); log.debug("Generated new S3 path for deleted document: {}", newS3Path); UploadFileOnAmazonS3Response response = amazonS3Service.moveFile(applicationSignedDocumentEntity.getFileName(), oldS3Path, newS3Path); @@ -1418,7 +1421,7 @@ public class ApplicationDao { } private String generateS3PathForDelegation(Long callId, Long applicationId) { try { - return s3ConfigBean.generateDocumentPathForOther(DocOtherSourceTypeEnum.USER_SIGNED_DOCUMENT, callId, applicationId,0L,0L); + return s3ConfigBean.generateDocumentPathForOther(DocOtherSourceTypeEnum.USER_SIGNED_DOCUMENT, callId, applicationId,0L,0L,0L); } catch (IllegalArgumentException e) { log.error("Failed to generate S3 path for delegation | callId: {}, applicationId: {}, error: {}", callId, applicationId, e.getMessage(), e); throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.S3_PATH_GENERATION_ERROR_MSG)); @@ -1541,11 +1544,12 @@ public class ApplicationDao { List amendmentDocuments = fetchAmendmentDocuments(applicationId); List evaluationDocuments = fetchEvaluationDocuments(applicationId); List communicationnDocuments = fetchCommunicationDocuments(applicationId); + List contractDocuments=fetchContractDocuments(applicationId); if (documents.isEmpty() && signedDocument == null && amendmentDocuments.isEmpty() && evaluationDocuments.isEmpty()) { log.warn("No documents found for applicationId: {}", applicationId); throw new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.DOCUMENT_NOT_FOUND)); } - return createZipWithDocuments(applicationEntity, documents, signedDocument, amendmentDocuments, evaluationDocuments, applicationId,communicationnDocuments); + return createZipWithDocuments(applicationEntity, documents, signedDocument, amendmentDocuments, evaluationDocuments, applicationId,communicationnDocuments,contractDocuments); } private void validateAssignedUser(HttpServletRequest request, Long applicationId) { @@ -1637,12 +1641,12 @@ public class ApplicationDao { } } private byte[] createZipWithDocuments(ApplicationEntity applicationEntity, List documents, ApplicationSignedDocumentEntity signedDocument, - List amendmentDocuments, List evaluationDocuments, Long applicationId,List communicationDocuments) { + List amendmentDocuments, List evaluationDocuments, Long applicationId,List communicationDocuments,List contractDocuments) { try (ByteArrayOutputStream zipOutputStream = new ByteArrayOutputStream(); ZipOutputStream zos = new ZipOutputStream(zipOutputStream)) { Long callId = applicationEntity.getCall().getId(); // Add Application Documents - String appS3Folder = s3PathConfig.generateDocumentPath(DocumentSourceTypeEnum.APPLICATION, callId, applicationId, 0L,0L); + String appS3Folder = s3PathConfig.generateDocumentPath(DocumentSourceTypeEnum.APPLICATION, callId, applicationId, 0L,0L,0L); for (DocumentEntity document : documents) { String fileName = Utils.extractFileName(document.getFilePath()); addDocumentToZip(zos, appS3Folder, document.getFilePath(), fileName); @@ -1650,7 +1654,7 @@ public class ApplicationDao { // Add Signed Document if (signedDocument != null) { String signedFolder = "SIGNED_DOCUMENT/"; - String signedDocS3Folder = s3PathConfig.generateDocumentPathForOther(DocOtherSourceTypeEnum.USER_SIGNED_DOCUMENT, callId, applicationId, 0L,0L); + String signedDocS3Folder = s3PathConfig.generateDocumentPathForOther(DocOtherSourceTypeEnum.USER_SIGNED_DOCUMENT, callId, applicationId, 0L,0L,0L); String fileName = signedDocument.getFileName(); addDocumentToZip(zos, signedDocS3Folder, signedDocument.getFilePath(), signedFolder + fileName); } @@ -1658,23 +1662,30 @@ public class ApplicationDao { for (DocumentEntity amendmentDocument : amendmentDocuments) { String protocolNumber = fetchProtocolNumberForAmendment(amendmentDocument.getSourceId()); String amendmentFolder = "SOCCORSO_" + protocolNumber + "/"; - String amendmentS3Folder = s3PathConfig.generateDocumentPath(DocumentSourceTypeEnum.AMENDMENT, callId, applicationId, amendmentDocument.getSourceId(),0L); + String amendmentS3Folder = s3PathConfig.generateDocumentPath(DocumentSourceTypeEnum.AMENDMENT, callId, applicationId, amendmentDocument.getSourceId(),0L,0L); String fileName = Utils.extractFileName(amendmentDocument.getFilePath()); addDocumentToZip(zos, amendmentS3Folder, amendmentDocument.getFilePath(), amendmentFolder + fileName); } // Add Evaluation Documents for (DocumentEntity evaluationDocument : evaluationDocuments) { String evaluationFolder = "EVALUATION/"; - String evaluationS3Folder = s3PathConfig.generateDocumentPath(DocumentSourceTypeEnum.EVALUATION, callId, applicationId, evaluationDocument.getSourceId(),0L); + String evaluationS3Folder = s3PathConfig.generateDocumentPath(DocumentSourceTypeEnum.EVALUATION, callId, applicationId, evaluationDocument.getSourceId(),0L,0L); String fileName = Utils.extractFileName(evaluationDocument.getFilePath()); addDocumentToZip(zos, evaluationS3Folder, evaluationDocument.getFilePath(), evaluationFolder + fileName); } for (DocumentEntity communicationDocument : communicationDocuments) { Optional communicationEntity=communicationRepository.findByIdAndIsDeletedFalse(communicationDocument.getSourceId()); - String evaluationFolder = "COMMUNICATION/"; - String evaluationS3Folder = s3PathConfig.generateDocumentPath(DocumentSourceTypeEnum.COMMUNICATION, callId, applicationId, communicationEntity.get().getApplicationAmendmentRequest().getId(),communicationDocument.getSourceId()); + String communicationFolder = "COMMUNICATION/"; + String communicationS3Folder = s3PathConfig.generateDocumentPath(DocumentSourceTypeEnum.COMMUNICATION, callId, applicationId, communicationEntity.get().getApplicationAmendmentRequest().getId(),communicationDocument.getSourceId(),0L); String fileName = Utils.extractFileName(communicationDocument.getFilePath()); - addDocumentToZip(zos, evaluationS3Folder, communicationDocument.getFilePath(), evaluationFolder + fileName); + addDocumentToZip(zos, communicationS3Folder, communicationDocument.getFilePath(), communicationFolder + fileName); + } + for (DocumentEntity contractDocument : contractDocuments) { + ApplicationContractEntity applicationContractEntity=applicationContractRepository.findByIdAndIsDeletedFalse(contractDocument.getSourceId()); + String contractFolder = "CONTRACT/"; + String contractS3Folder = s3PathConfig.generateDocumentPath(DocumentSourceTypeEnum.CONTRACT, callId, applicationId, 0L,contractDocument.getSourceId(),applicationContractEntity.getApplicationId()); + String fileName = Utils.extractFileName(contractDocument.getFilePath()); + addDocumentToZip(zos, contractS3Folder, contractDocument.getFilePath(), contractFolder + fileName); } zos.finish(); return zipOutputStream.toByteArray(); @@ -2599,5 +2610,18 @@ public class ApplicationDao { return out.toByteArray(); } + private List fetchContractDocuments(Long applicationId) { + log.info("Fetching contract documents for applicationId: {}", applicationId); + ApplicationContractEntity applicationContractEntity=applicationContractRepository.findByApplicationIdAndIsDeletedFalse(applicationId); + List documentEntities=new ArrayList<>(); + if(applicationContractEntity!=null){ + Long contractId = applicationContractEntity.getId(); + log.debug("Found contract entity with id: {}", contractId); + List communicationDocuments= documentRepository.findBySourceIdInAndSourceAndIsDeletedFalse(Collections.singleton(contractId), DocumentSourceTypeEnum.CONTRACT.getValue()); + documentEntities.addAll(communicationDocuments); + return documentEntities; + } + return Collections.emptyList(); + } } diff --git a/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java b/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java index 0f688aaf..f5c2b7c0 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java @@ -155,7 +155,7 @@ public class CallDao { for (DocumentEntity document : documents) { log.info("Adding document to ZIP: documentId={}, fileName={}", document.getId(), document.getFileName()); - String s3Folder = s3PathConfig.generateDocumentPath(DocumentSourceTypeEnum.CALL, callId, 0L,0L,0L); + String s3Folder = s3PathConfig.generateDocumentPath(DocumentSourceTypeEnum.CALL, callId, 0L,0L,0L,0L); try (InputStream fileInputStream = amazonS3Service.getFile(s3Folder, document.getFilePath())) { String fileName = Utils.extractFileName(document.getFilePath()); ZipEntry zipEntry = new ZipEntry(fileName); diff --git a/src/main/java/net/gepafin/tendermanagement/dao/CompanyDocumentDao.java b/src/main/java/net/gepafin/tendermanagement/dao/CompanyDocumentDao.java index 2f25bd75..c034a985 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/CompanyDocumentDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/CompanyDocumentDao.java @@ -281,7 +281,7 @@ public class CompanyDocumentDao { validator.validateUserWithCompany(request,companyDocumentEntity.getCompanyId()); String companyDocumentPath = companyDocumentEntity.getFilePath(); - String documentPath = s3ConfigBean.generateDocumentPath(DocumentSourceTypeEnum.APPLICATION,applicationEntity.getCall().getId(),applicationId,0L,0L); + String documentPath = s3ConfigBean.generateDocumentPath(DocumentSourceTypeEnum.APPLICATION,applicationEntity.getCall().getId(),applicationId,0L,0L,0L); log.info("Original Paths - oldPath: {}, newPath: {}", companyDocumentPath, documentPath); diff --git a/src/main/java/net/gepafin/tendermanagement/dao/DelegationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/DelegationDao.java index 6af7e820..24d9c15e 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/DelegationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/DelegationDao.java @@ -92,7 +92,7 @@ public class DelegationDao { public ByteArrayOutputStream generateDocument(Map placeholders, String templateName) { try { - String s3Folder = s3ConfigBean.generateDocumentPathForOther(DocOtherSourceTypeEnum.TEMPLATE, 0L, 0L,0L,0L); + String s3Folder = s3ConfigBean.generateDocumentPathForOther(DocOtherSourceTypeEnum.TEMPLATE, 0L, 0L,0L,0L,0L); InputStream templateStream = amazonS3Service.getFile(s3Folder ,templateName); XWPFDocument doc = loadTemplate(templateStream); replacePlaceholders(doc, placeholders); diff --git a/src/main/java/net/gepafin/tendermanagement/dao/DocumentDao.java b/src/main/java/net/gepafin/tendermanagement/dao/DocumentDao.java index 5fdf7e99..810fec9c 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/DocumentDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/DocumentDao.java @@ -93,6 +93,9 @@ public class DocumentDao { @Autowired private CommunicationRepository communicationRepository; + @Autowired + private ApplicationContractRepository applicationContractRepository; + // @Value("${aws.s3.url.folder}") // private String s3Folder; @@ -172,6 +175,7 @@ public class DocumentDao { Long amendmentId = 0L; Long evaluationId = 0L; Long communicationId = 0L; + Long contractId=0L; Long callId = sourceId; if (type == DocumentSourceTypeEnum.APPLICATION) { applicationId = sourceId; @@ -197,9 +201,16 @@ public class DocumentDao { applicationId=applicationAmendmentRequestEntity.get().getApplicationId(); callId = applicationAmendmentRequestEntity.get().getApplicationEvaluationEntity().getAssignedApplicationsEntity().getApplication().getCall().getId(); log.info("Processing document of type COMMUNICATION .Resolved evaluationId={}, applicationId={}, callId={}", evaluationId, applicationId, callId); + }else if (type == DocumentSourceTypeEnum.CONTRACT) { + contractId = sourceId; + ApplicationContractEntity applicationContractEntity=applicationContractRepository.findByIdAndIsDeletedFalse(contractId); + ApplicationEntity applicationEntity=applicationService.validateApplication(applicationContractEntity.getApplicationId()); + applicationId=applicationEntity.getId(); + callId = applicationEntity.getCall().getId(); + log.info("Processing document of type CONTRACT .Resolved evaluationId={}, applicationId={}, callId={}, contractId={}", evaluationId, applicationId, callId,contractId); } try { - String s3Path = generateS3Path(type, callId, applicationId, amendmentId,communicationId); + String s3Path = generateS3Path(type, callId, applicationId, amendmentId,communicationId,contractId); log.info("Generated S3 path {}", s3Path); return amazonS3Service.uploadFileOnAmazonS3(s3Path, file); } catch (Exception e) { @@ -210,9 +221,9 @@ public class DocumentDao { } - public String generateS3Path(DocumentSourceTypeEnum typeOfDocument, Long callId, Long applicationId, Long amendmentId,Long communicationId) { + public String generateS3Path(DocumentSourceTypeEnum typeOfDocument, Long callId, Long applicationId, Long amendmentId,Long communicationId,Long contractId) { try { - return s3ConfigBean.generateDocumentPath(typeOfDocument, callId, applicationId, amendmentId,communicationId); + return s3ConfigBean.generateDocumentPath(typeOfDocument, callId, applicationId, amendmentId,communicationId,contractId); } catch (IllegalArgumentException e) { throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.S3_PATH_GENERATION_ERROR_MSG)); } @@ -245,6 +256,7 @@ public class DocumentDao { Long amendmentId = null; Long evaluationId = null; Long communicationId=null; + Long contractId=null; if (DocumentSourceTypeEnum.CALL.getValue().equalsIgnoreCase(documentEntity.getSource())) { callId = documentEntity.getSourceId(); @@ -340,9 +352,20 @@ public class DocumentDao { communicationEntity1.setDocuments(updatedValue); communicationRepository.save(communicationEntity1); } + } + else if(DocumentSourceTypeEnum.CONTRACT.getValue().equalsIgnoreCase(documentEntity.getSource())) { + contractId = documentEntity.getSourceId(); + ApplicationContractEntity applicationContractEntity=applicationContractRepository.findByIdAndIsDeletedFalse(contractId); + ApplicationEntity applicationEntity=applicationService.validateApplication(applicationContractEntity.getApplicationId()); + String beneficiaryDocument=applicationContractEntity.getBeneficiaryDocument(); + if(beneficiaryDocument!=null) { + String updatedValue = removeDocumentIdFromFieldValue(beneficiaryDocument, documentId); + applicationContractEntity.setBeneficiaryDocument(updatedValue); + applicationContractRepository.save(applicationContractEntity); + } } - deleteFileFromS3(documentEntity, callId, applicationId,amendmentId,communicationId); + deleteFileFromS3(documentEntity, callId, applicationId,amendmentId,communicationId,contractId); log.info("Successfully deleted file from S3 for documentId={}", documentId); } @@ -387,6 +410,7 @@ public class DocumentDao { Long amendmentId=null; Long evaluationId=null; Long communicationId=null; + Long contractId=null; if (type.equals(DocumentSourceTypeEnum.APPLICATION)) { callId = applicationRepository.findCallIdById(id); applicationId = id; @@ -412,6 +436,13 @@ public class DocumentDao { applicationId=applicationAmendmentRequestEntity.get().getApplicationId(); callId = applicationAmendmentRequestEntity.get().getApplicationEvaluationEntity().getAssignedApplicationsEntity().getApplication().getCall().getId(); log.info("Processing document of type EVALUATION .Resolved evaluationId={}, applicationId={}, callId={}", evaluationId, applicationId, callId); + }else if (type == DocumentSourceTypeEnum.CONTRACT) { + contractId = id; + ApplicationContractEntity applicationContractEntity=applicationContractRepository.findByIdAndIsDeletedFalse(contractId); + ApplicationEntity applicationEntity=applicationService.validateApplication(applicationContractEntity.getApplicationId()); + applicationId=applicationContractEntity.getApplicationId(); + callId = applicationEntity.getCall().getId(); + log.info("Processing document of type CONTRACT .Resolved evaluationId={}, applicationId={}, callId={}, contractId={}", evaluationId, applicationId, callId,contractId); } else { @@ -419,7 +450,7 @@ public class DocumentDao { applicationId = 0L; log.info("Processing document of type CALL . Resolved callId={}", callId); } - String s3Path = generateS3Path(type, callId, applicationId,amendmentId,communicationId); + String s3Path = generateS3Path(type, callId, applicationId,amendmentId,communicationId,contractId); log.info("Generated S3 path {}", s3Path); return amazonS3Service.uploadFileOnAmazonS3(s3Path, file); } catch (Exception e) { @@ -432,12 +463,12 @@ public class DocumentDao { return callDao.convertToDocumentResponseBean(documentEntity); } - public void deleteFileFromS3(DocumentEntity documentEntity, Long callId, Long applicationId,Long amendmentId,Long communicationId) { + public void deleteFileFromS3(DocumentEntity documentEntity, Long callId, Long applicationId,Long amendmentId,Long communicationId,Long contractId) { try { DocumentEntity oldDocumentEntity = Utils.getClonedEntityForData(documentEntity); String oldS3Path = documentEntity.getFilePath(); - String newS3Path = s3ConfigBean.generateDocumentPathForOther(DocOtherSourceTypeEnum.valueOf("DELETED_" + documentEntity.getSource().toUpperCase()), callId, applicationId,amendmentId,communicationId); + String newS3Path = s3ConfigBean.generateDocumentPathForOther(DocOtherSourceTypeEnum.valueOf("DELETED_" + documentEntity.getSource().toUpperCase()), callId, applicationId,amendmentId,communicationId,contractId); log.info("Moving file to deleted path: oldS3Path={}, newS3Path={}", oldS3Path, newS3Path); UploadFileOnAmazonS3Response response = amazonS3Service.moveFile(documentEntity.getFileName(), oldS3Path, newS3Path); documentEntity.setFileName(response.getFileName()); diff --git a/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java index 1d7ebd86..da689b79 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java @@ -97,6 +97,9 @@ public class EmailNotificationDao { @Autowired private ApplicationDao applicationDao; + @Autowired + private ApplicationContractDao applicationContractDao; + public void sendEmail(ApplicationEntity applicationEntity, SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum templateType, Map bodyPlaceholders, List additionalRecipients, Long amendmentId,String emailType) { @@ -106,7 +109,7 @@ public class EmailNotificationDao { EmailContentResponse emailContent = prepareEmailContent(applicationEntity, templateType, hubEntity, bodyPlaceholders,emailType); UserEntity userEntity = userService.validateUser(applicationEntity.getUserId()); - sendEmails(applicationEntity, userEntity, additionalRecipients,amendmentId,emailContent.getSystemEmailTemplateResponse(),emailContent.getSubject(),emailContent.getBody()); + sendEmails(applicationEntity, userEntity, additionalRecipients,amendmentId,emailContent.getSystemEmailTemplateResponse(),emailContent.getSubject(),emailContent.getBody(),null); } public EmailContentResponse prepareEmailContent( @@ -131,7 +134,7 @@ public class EmailNotificationDao { return new EmailContentResponse(subject, body, systemEmailTemplateResponse); } - private void sendEmails(ApplicationEntity applicationEntity, UserEntity userEntity, List additionalRecipients,Long amendmentId,SystemEmailTemplateResponse systemEmailTemplateResponse,String subject,String body) { + private void sendEmails(ApplicationEntity applicationEntity, UserEntity userEntity, List additionalRecipients,Long amendmentId,SystemEmailTemplateResponse systemEmailTemplateResponse,String subject,String body,Long contractId) { Optional applicationEvaluationEntity = applicationEvaluationRepository.findByApplicationIdAndIsDeletedFalse(applicationEntity.getId()); CompanyEntity company = companyService.validateCompany(applicationEntity.getCompanyId()); @@ -177,6 +180,14 @@ public class EmailNotificationDao { : new HashSet<>(documentIds); documentEntities=documentRepository.findAllByIdInAndIsDeletedFalse(setOfDocumentIds); } + if(Boolean.TRUE.equals(userEntity.getHub().getUniqueUuid().equals(defaultHubUuid)) && Boolean.TRUE.equals(systemEmailTemplateResponse.getEmailScenario().equals(EmailScenarioTypeEnum.APPLICATION_CONTRACT_CREATED))) { + ApplicationContractEntity applicationContractEntity=applicationContractDao.validateApplicationContract(contractId); + List documentIds=applicationDao.validateDocumentIds(applicationContractEntity.getInstructorDocument()); + Set setOfDocumentIds = (documentIds == null) + ? Collections.emptySet() + : new HashSet<>(documentIds); + documentEntities=documentRepository.findAllByIdInAndIsDeletedFalse(setOfDocumentIds); + } urls = documentEntities.stream() .map(DocumentEntity::getFilePath) // or getUrl() @@ -225,7 +236,7 @@ public class EmailNotificationDao { } } - if (userEntity.getBeneficiary().getEmail() != null) { + if (userEntity.getBeneficiary()!= null) { String beneficiaryEmail = null; RecipientTypeEnum recipientTypeEnum=RecipientTypeEnum.BENEFICIARY; if (Boolean.TRUE.equals(userEntity.getHub().getUniqueUuid().equals(defaultHubUuid))){ @@ -514,4 +525,33 @@ public class EmailNotificationDao { sendEmail(applicationEntity, SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum.SPECIAL_APPLICATION_AMENDMENT_REQUESTED, bodyPlaceholders, null, applicationAmendmentRequestEntity.getId(),null); } + public void sendEmailForApplicationContracted(ApplicationEntity applicationEntity,ApplicationContractEntity applicationContractEntity,UserEntity user) { + Map bodyPlaceholders = new HashMap<>(); + bodyPlaceholders.put("{{call_name}}", applicationEntity.getCall().getName()); + String protocolNumber=applicationEntity.getProtocol().getExternalProtocolNumber(); + if(protocolNumber==null){ + protocolNumber= String.valueOf(applicationEntity.getProtocol().getProtocolNumber()); + } + bodyPlaceholders.put("{{protocol_number}}", protocolNumber); + String protocolDate= DateTimeUtil.formatLocalDateTime(applicationEntity.getProtocol().getCreatedDate(), GepafinConstant.DD_MM_YYYY); + if(applicationEntity.getProtocol().getExternalProtocolDate()!=null){ + protocolDate= DateTimeUtil.formatLocalDateTime(applicationEntity.getProtocol().getExternalProtocolDate(), GepafinConstant.DD_MM_YYYY); + } + bodyPlaceholders.put("{{protocol_date}}", protocolDate); + bodyPlaceholders.put("{{protocol_time}}", DateTimeUtil.parseLocalTimeToString(applicationEntity.getProtocol().getTime(), GepafinConstant.HH_MM_SS)); + HubEntity hubEntity = hubService.valdateHub(applicationEntity.getHubId()); + Map subjectPlaceholders = new HashMap<>(); + CompanyEntity company = companyService.validateCompany(applicationEntity.getCompanyId()); + subjectPlaceholders.put("{{call_name}}", applicationEntity.getCall().getName()); + subjectPlaceholders.put("{{company_name}}", company.getCompanyName()); +// bodyPlaceholders.put("{{legal_mail}}", legalMail); + String subject = Utils.replacePlaceholders(applicationContractEntity.getSubject(), subjectPlaceholders); + String body = Utils.replacePlaceholders(applicationContractEntity.getText(), bodyPlaceholders); + SystemEmailTemplateResponse systemEmailTemplateResponse=new SystemEmailTemplateResponse(); + systemEmailTemplateResponse.setSubject(subject); + systemEmailTemplateResponse.setHtmlContent(body); + systemEmailTemplateResponse.setEmailScenario(EmailScenarioTypeEnum.APPLICATION_CONTRACT_CREATED); + EmailContentResponse emailContentResponse= new EmailContentResponse(subject, body, systemEmailTemplateResponse); + sendEmails(applicationEntity, user, null,null,emailContentResponse.getSystemEmailTemplateResponse(),emailContentResponse.getSubject(),emailContentResponse.getBody(),applicationContractEntity.getId()); + } } \ No newline at end of file diff --git a/src/main/java/net/gepafin/tendermanagement/dao/S3PathConfig.java b/src/main/java/net/gepafin/tendermanagement/dao/S3PathConfig.java index 9cbc1b26..a3b82544 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/S3PathConfig.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/S3PathConfig.java @@ -15,27 +15,28 @@ public class S3PathConfig { @Autowired S3ConfigRepository s3ConfigRepository; - public String generateDocumentPath(DocumentSourceTypeEnum type, Long callId, Long applicationId,Long amendmentId,Long communicationId) { + public String generateDocumentPath(DocumentSourceTypeEnum type, Long callId, Long applicationId,Long amendmentId,Long communicationId,Long contractId) { S3ConfigEntity config = getDocumentPath(type); - return config.getParentFolder() + "/" + buildS3Path(config.getPath(), callId, applicationId,amendmentId,communicationId); + return config.getParentFolder() + "/" + buildS3Path(config.getPath(), callId, applicationId,amendmentId,communicationId,contractId); } - public String generateDocumentPathForOther(DocOtherSourceTypeEnum type, Long callId, Long applicationId,Long amendmentId,Long communicationId) { + public String generateDocumentPathForOther(DocOtherSourceTypeEnum type, Long callId, Long applicationId,Long amendmentId,Long communicationId,Long contractId) { S3ConfigEntity config = getDocumentPathForOther(type); - return config.getParentFolder() + "/" + buildS3Path(config.getPath(), callId, applicationId,amendmentId,communicationId); + return config.getParentFolder() + "/" + buildS3Path(config.getPath(), callId, applicationId,amendmentId,communicationId,contractId); } public String generateDocumentPathForDelegationAndSignedDocument(DocOtherSourceTypeEnum type) { S3ConfigEntity config = getDocumentPathForOther(type); return config.getParentFolder() + "/" + config.getPath(); } - private String buildS3Path(String pathTemplate, Long callId, Long applicationId, Long amendmentId,Long communicationId) { + private String buildS3Path(String pathTemplate, Long callId, Long applicationId, Long amendmentId,Long communicationId,Long contractId) { return pathTemplate .replace("{call_id}", callId != null && callId != 0L ? "call_" + callId : "") .replace("{application_id}", applicationId != null && applicationId != 0L ? "application_" + applicationId : "") .replace("{amendment_id}", amendmentId != null && amendmentId != 0L ? "amendment_" + amendmentId : "") - .replace("{communication_id}", communicationId != null && communicationId != 0L ? "communication_" + communicationId : ""); + .replace("{communication_id}", communicationId != null && communicationId != 0L ? "communication_" + communicationId : "") + .replace("{contract_id}", contractId != null && contractId != 0L ? "contract_" + contractId : ""); } private S3ConfigEntity getDocumentPath(DocumentSourceTypeEnum type) { diff --git a/src/main/java/net/gepafin/tendermanagement/entities/ApplicationContractEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/ApplicationContractEntity.java new file mode 100644 index 00000000..d482e5d2 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/entities/ApplicationContractEntity.java @@ -0,0 +1,46 @@ +package net.gepafin.tendermanagement.entities; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Table; +import lombok.Data; +import org.hibernate.annotations.Where; + +import java.time.LocalDateTime; + +@Entity +@Table(name = "APPLICATION_CONTRACT") +@Data +@Where(clause = "is_deleted = false") +public class ApplicationContractEntity extends BaseEntity{ + + @Column(name = "SUBJECT") + private String subject; + + @Column(name = "TEXT") + private String text; + + @Column(name = "INSTRUCTOR_DOCUMENT") + private String instructorDocument; + + @Column(name = "STATUS") + private String status; + + @Column(name = "BENEFICIARY_DOCUMENT") + private String beneficiaryDocument; + + @Column(name = "BENEFICIARY_USER_ID") + private Long beneficiaryUserId; + + @Column(name = "INSTRUCTOR_ID") + private Long instructorId; + + @Column(name = "IS_DELETED") + private Boolean isDeleted; + + @Column(name = "COMPLETION_DATE") + private LocalDateTime completionDate; + + @Column(name = "APPLICATION_ID") + private Long applicationId; +} diff --git a/src/main/java/net/gepafin/tendermanagement/enums/ApplicationContractStatusEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/ApplicationContractStatusEnum.java new file mode 100644 index 00000000..9483fe01 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/enums/ApplicationContractStatusEnum.java @@ -0,0 +1,22 @@ +package net.gepafin.tendermanagement.enums; + +import com.fasterxml.jackson.annotation.JsonValue; + +public enum ApplicationContractStatusEnum { + + DRAFT("DRAFT"), + + SIGNED("SIGNED"); + + + private final String value; + + ApplicationContractStatusEnum(String value) { + this.value = value; + } + + @JsonValue + public String getValue() { + return value; + } +} diff --git a/src/main/java/net/gepafin/tendermanagement/enums/ApplicationStatusTypeEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/ApplicationStatusTypeEnum.java index fd48ab9a..d686a347 100644 --- a/src/main/java/net/gepafin/tendermanagement/enums/ApplicationStatusTypeEnum.java +++ b/src/main/java/net/gepafin/tendermanagement/enums/ApplicationStatusTypeEnum.java @@ -18,7 +18,9 @@ public enum ApplicationStatusTypeEnum { ADMISSIBLE("ADMISSIBLE"), TECHNICAL_EVALUATION("TECHNICAL_EVALUATION"), TECHNICAL_EVALUATION_REJECTED("TECHNICAL_EVALUATION_REJECTED"), - AWAITING_TECHNICAL_EVALUATION("AWAITING_TECHNICAL_EVALUATION") ; + AWAITING_TECHNICAL_EVALUATION("AWAITING_TECHNICAL_EVALUATION"), + AWAITING_CONTRACT("AWAITING_CONTRACT"), + CONTRACT_SIGNED("CONTRACT_SIGNED"); private String value; diff --git a/src/main/java/net/gepafin/tendermanagement/enums/DocumentSourceTypeEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/DocumentSourceTypeEnum.java index 2e10a873..68d482fb 100644 --- a/src/main/java/net/gepafin/tendermanagement/enums/DocumentSourceTypeEnum.java +++ b/src/main/java/net/gepafin/tendermanagement/enums/DocumentSourceTypeEnum.java @@ -6,7 +6,8 @@ public enum DocumentSourceTypeEnum { APPLICATION("APPLICATION"), EVALUATION("EVALUATION"), AMENDMENT("AMENDMENT"), - COMMUNICATION("COMMUNICATION"); + COMMUNICATION("COMMUNICATION"), + CONTRACT("CONTRACT"); 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 c459239d..fe8d64b2 100644 --- a/src/main/java/net/gepafin/tendermanagement/enums/EmailScenarioTypeEnum.java +++ b/src/main/java/net/gepafin/tendermanagement/enums/EmailScenarioTypeEnum.java @@ -14,7 +14,8 @@ public enum EmailScenarioTypeEnum { APPLICATION_REJECTED("APPLICATION_REJECTED"), APPLICATION_SUBMISSION_FAILURE("APPLICATION_SUBMISSION_FAILURE"), APPLICATION_TECHNICAL_EVALUATION_REJECTED("APPLICATION_TECHNICAL_EVALUATION_REJECTED"), - SPECIAL_APPLICATION_AMENDMENT_REQUESTED("SPECIAL_APPLICATION_AMENDMENT_REQUESTED"); + SPECIAL_APPLICATION_AMENDMENT_REQUESTED("SPECIAL_APPLICATION_AMENDMENT_REQUESTED"), + APPLICATION_CONTRACT_CREATED("APPLICATION_CONTRACT_CREATED"); private final String value; diff --git a/src/main/java/net/gepafin/tendermanagement/enums/NotificationTypeEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/NotificationTypeEnum.java index 4430c2d6..c979bb2a 100644 --- a/src/main/java/net/gepafin/tendermanagement/enums/NotificationTypeEnum.java +++ b/src/main/java/net/gepafin/tendermanagement/enums/NotificationTypeEnum.java @@ -15,7 +15,8 @@ public enum NotificationTypeEnum { AMENDMENT_EXPIRATION_REMINDER("AMENDMENT_EXPIRATION_REMINDER"), EVALUATION_EXPIRATION_REMINDER("EVALUATION_EXPIRATION_REMINDER"), COMPANY_DOCUMENT_EXPIRATION_REMINDER("COMPANY_DOCUMENT_EXPIRATION_REMINDER"), - PEC_EMAIL_SENDING_FAILURE("PEC_EMAIL_SENDING_FAILURE"); + PEC_EMAIL_SENDING_FAILURE("PEC_EMAIL_SENDING_FAILURE"), + CONTRACT_UPLOAD("CONTRACT_UPLOAD"); 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 32847535..98aca8cf 100644 --- a/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java +++ b/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java @@ -224,7 +224,13 @@ public enum UserActionContextEnum { RESEND_EMAIL("RESEND_EMAIL"), SEND_REMINDER_EMAIL("SEND_REMINDER_EMAIL"), CREATE_SPECIAL_AMENDMENT("CREATE_SPECIAL_AMENDMENT"), - UPDATE_APPLICATION_TO_TECHNICAL_EVALUATION_REJECTED("UPDATE_APPLICATION_TO_TECHNICAL_EVALUATION_REJECTED"); + UPDATE_APPLICATION_TO_TECHNICAL_EVALUATION_REJECTED("UPDATE_APPLICATION_TO_TECHNICAL_EVALUATION_REJECTED"), + CREATE_CONTRACT_FOR_APPLICATION("CREATE_CONTRACT_FOR_APPLICATION"), + UPDATE_APPLICATION_CONTRACT("UPDATE_APPLICATION_CONTRACT"), + FETCH_APPLICATION_CONTRACT("FETCH_APPLICATION_CONTRACT"), + FETCH_APPLICATION_CONTRACT_BY_APPLICATION_ID("FETCH_APPLICATION_CONTRACT_BY_APPLICATION_ID"), + FETCH_APPLICATION_CONTRACT_BY_BENEFICIARY_USER_ID("FETCH_APPLICATION_CONTRACT_BY_BENEFICIARY_USER_ID"); + private final String value; diff --git a/src/main/java/net/gepafin/tendermanagement/model/request/ApplicationContractRequest.java b/src/main/java/net/gepafin/tendermanagement/model/request/ApplicationContractRequest.java new file mode 100644 index 00000000..25e875b6 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/model/request/ApplicationContractRequest.java @@ -0,0 +1,10 @@ +package net.gepafin.tendermanagement.model.request; + +import lombok.Data; + +@Data +public class ApplicationContractRequest { + + private String subject; + private String text; +} diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationContractResponse.java b/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationContractResponse.java new file mode 100644 index 00000000..d3d19dac --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationContractResponse.java @@ -0,0 +1,30 @@ +package net.gepafin.tendermanagement.model.response; + +import lombok.Data; +import net.gepafin.tendermanagement.enums.ApplicationContractStatusEnum; + +import java.time.LocalDateTime; +import java.util.List; + +@Data +public class ApplicationContractResponse { + + private Long id; + + private String subject; + + private String text; + + private ApplicationContractStatusEnum status; + + private List instructorDocuments; + + private Long instructorId; + + private List beneficiaryDocuments; + + private Long beneficiaryUserId; + + private LocalDateTime completionDate; + +} diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationContractRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationContractRepository.java new file mode 100644 index 00000000..0f8d3d27 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationContractRepository.java @@ -0,0 +1,18 @@ +package net.gepafin.tendermanagement.repositories; + +import net.gepafin.tendermanagement.entities.ApplicationContractEntity; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +public interface ApplicationContractRepository extends JpaRepository { + + ApplicationContractEntity findByIdAndIsDeletedFalse(Long id); + + ApplicationContractEntity findByApplicationIdAndIsDeletedFalse(Long applicationId); + + List findByBeneficiaryUserIdAndStatusAndIsDeletedFalse(Long applicationId,String status); + +} diff --git a/src/main/java/net/gepafin/tendermanagement/service/ApplicationContractService.java b/src/main/java/net/gepafin/tendermanagement/service/ApplicationContractService.java new file mode 100644 index 00000000..bf562cdf --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/service/ApplicationContractService.java @@ -0,0 +1,21 @@ +package net.gepafin.tendermanagement.service; + +import jakarta.servlet.http.HttpServletRequest; +import net.gepafin.tendermanagement.model.request.ApplicationContractRequest; +import net.gepafin.tendermanagement.model.response.ApplicationContractResponse; +import org.springframework.web.multipart.MultipartFile; + +import java.util.List; + +public interface ApplicationContractService { + + public ApplicationContractResponse createApplicationContract(HttpServletRequest httpServletRequest, Long applicationId, List contractDocuments, ApplicationContractRequest applicationContractRequest); + + public ApplicationContractResponse updateApplicationContract(HttpServletRequest httpServletRequest, Long applicationContractId,List beneficiaryContractDocuments); + + public ApplicationContractResponse getContractById(Long contractId); + + public ApplicationContractResponse getContractByApplicationId(Long applicationContractId); + + List getContractByBeneficiaryUserId(Long beneficiaryUserId); + } diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationContractServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationContractServiceImpl.java new file mode 100644 index 00000000..5e1ea5c0 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationContractServiceImpl.java @@ -0,0 +1,68 @@ +package net.gepafin.tendermanagement.service.impl; + +import jakarta.servlet.http.HttpServletRequest; +import net.gepafin.tendermanagement.config.Translator; +import net.gepafin.tendermanagement.constants.GepafinConstant; +import net.gepafin.tendermanagement.dao.ApplicationContractDao; +import net.gepafin.tendermanagement.dao.UserDao; +import net.gepafin.tendermanagement.entities.UserEntity; +import net.gepafin.tendermanagement.model.request.ApplicationContractRequest; +import net.gepafin.tendermanagement.model.response.ApplicationContractResponse; +import net.gepafin.tendermanagement.service.ApplicationContractService; +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.Status; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; + +import java.util.List; +import java.util.Map; + +@Service +public class ApplicationContractServiceImpl implements ApplicationContractService { + + @Autowired + private ApplicationContractDao applicationContractDao; + + @Autowired + private Validator validator; + + @Autowired + private UserDao userDao; + + @Override + public ApplicationContractResponse createApplicationContract(HttpServletRequest httpServletRequest, Long applicationId, List contractDocuments, ApplicationContractRequest applicationContractRequest) { + UserEntity user= validator.validateUser(httpServletRequest); + if(contractDocuments==null) { + throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.FILES_REQUIRED_FOR_CONTRACT)); + } + contractDocuments.forEach(Utils::validateFileType); + return applicationContractDao.createApplicationContract(applicationId,contractDocuments,applicationContractRequest,user); + } + + @Override + public ApplicationContractResponse updateApplicationContract(HttpServletRequest httpServletRequest, Long applicationContractId, List beneficiaryContractDocuments) { + UserEntity user= validator.validateUser(httpServletRequest); + if(beneficiaryContractDocuments==null) { + throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.FILES_REQUIRED_FOR_CONTRACT)); + } + return applicationContractDao.updateApplicationContract(applicationContractId,beneficiaryContractDocuments,user); + } + + @Override + public ApplicationContractResponse getContractById(Long contractId) { + return applicationContractDao.getContractById(contractId); + } + + @Override + public ApplicationContractResponse getContractByApplicationId(Long applicationId) { + return applicationContractDao.getContractByApplicationId(applicationId); + } + @Override + public List getContractByBeneficiaryUserId(Long beneficiaryUserId) { + UserEntity user=userDao.validateUser(beneficiaryUserId); + return applicationContractDao.getContractByBeneficiaryUserId(user); + } +} diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/S3ReUploadMigrationService.java b/src/main/java/net/gepafin/tendermanagement/service/impl/S3ReUploadMigrationService.java index fdb09116..cbd6af2d 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/S3ReUploadMigrationService.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/S3ReUploadMigrationService.java @@ -9,6 +9,7 @@ import com.amazonaws.services.s3.model.ObjectMetadata; import lombok.extern.slf4j.Slf4j; import net.gepafin.tendermanagement.dao.DocumentDao; import net.gepafin.tendermanagement.dao.S3PathConfig; +import net.gepafin.tendermanagement.entities.ApplicationContractEntity; import net.gepafin.tendermanagement.entities.ApplicationEntity; import net.gepafin.tendermanagement.entities.CommunicationEntity; import net.gepafin.tendermanagement.entities.DocumentEntity; @@ -81,6 +82,9 @@ public class S3ReUploadMigrationService { @Autowired private DocumentDao documentDao; + @Autowired + private ApplicationContractRepository applicationContractRepository; + private boolean migrationCompleted = false; @@ -114,6 +118,7 @@ public class S3ReUploadMigrationService { Long amendmentId = null; Long evaluationId = null; Long communicationId=null; + Long contractId=null; if (DocumentSourceTypeEnum.CALL.getValue().equalsIgnoreCase(document.getSource())) { callId = document.getSourceId(); } else if (DocumentSourceTypeEnum.APPLICATION.getValue().equalsIgnoreCase(document.getSource())) { @@ -138,9 +143,15 @@ public class S3ReUploadMigrationService { applicationId = applicationEntity.getId(); callId = applicationEntity.getCall().getId(); } + else if(DocumentSourceTypeEnum.CONTRACT.getValue().equalsIgnoreCase(document.getSource())){ + contractId = document.getSourceId(); + ApplicationContractEntity applicationContractEntity=applicationContractRepository.findByIdAndIsDeletedFalse(contractId); + ApplicationEntity applicationEntity=applicationService.validateApplication(applicationContractEntity.getApplicationId()); + applicationId = applicationEntity.getId(); + callId = applicationEntity.getCall().getId(); + } - - documentDao.deleteFileFromS3(document,callId,applicationId,amendmentId,communicationId); + documentDao.deleteFileFromS3(document,callId,applicationId,amendmentId,communicationId,contractId); processDocuments++; } catch (Exception e) { @@ -231,10 +242,10 @@ public class S3ReUploadMigrationService { Long callId; if (sourceType.equals(DocumentSourceTypeEnum.CALL)) { - return s3ConfigBean.generateDocumentPath(sourceType, document.getSourceId(), 0L,0L,0L); + return s3ConfigBean.generateDocumentPath(sourceType, document.getSourceId(), 0L,0L,0L,0L); } else { callId = applicationRepository.findCallIdById(document.getSourceId()); - return s3ConfigBean.generateDocumentPath(sourceType, callId, document.getSourceId(),0L,0L); + return s3ConfigBean.generateDocumentPath(sourceType, callId, document.getSourceId(),0L,0L,0L); } } diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/UserSignedAndDelegationServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/UserSignedAndDelegationServiceImpl.java index e6ba7821..d86b96be 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/UserSignedAndDelegationServiceImpl.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/UserSignedAndDelegationServiceImpl.java @@ -139,7 +139,7 @@ public class UserSignedAndDelegationServiceImpl { private String generateNewS3PathForDelegationDoc() { - return s3ConfigBean.generateDocumentPathForOther(DocOtherSourceTypeEnum.USER_DELEGATION, 0L, 0L,0L,0L); + return s3ConfigBean.generateDocumentPathForOther(DocOtherSourceTypeEnum.USER_DELEGATION, 0L, 0L,0L,0L,0L); } private String generateNewS3PathForUserSignedDoc(ApplicationSignedDocumentEntity document) { diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/ApplicationContractApi.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/ApplicationContractApi.java new file mode 100644 index 00000000..c81e9a2b --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/ApplicationContractApi.java @@ -0,0 +1,96 @@ +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 jakarta.validation.Valid; +import net.gepafin.tendermanagement.model.request.ApplicationAmendmentSpecialRequest; +import net.gepafin.tendermanagement.model.request.ApplicationContractRequest; +import net.gepafin.tendermanagement.model.request.ApplicationEvaluationRequest; +import net.gepafin.tendermanagement.model.response.ApplicationAmendmentRequestResponse; +import net.gepafin.tendermanagement.model.response.ApplicationContractResponse; +import net.gepafin.tendermanagement.model.util.Response; +import net.gepafin.tendermanagement.web.rest.api.errors.ErrorConstants; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import java.util.List; + +@Validated +public interface ApplicationContractApi { + + @Operation(summary = "Api to create application contract", + 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 = "/application/{applicationId}", produces = "application/json", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) + @PreAuthorize("hasRole('ROLE_SUPER_ADMIN') || hasRole('ROLE_INSTRUCTOR_MANAGER')|| hasRole('ROLE_PRE_INSTRUCTOR')") + ResponseEntity> createApplicationContract(HttpServletRequest request, + @Parameter(description = "Application ID", required = true) @PathVariable("applicationId") Long applicationId, @Parameter(description = "List of files to upload", required = true) + @RequestPart(required = true) List contractDocuments, + @Parameter(description = "Application Contract Request Body", required = true) @RequestPart ApplicationContractRequest applicationContractRequest); + + @Operation(summary = "Api to update application contract from beneficiary side", + 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) })) }) + @PutMapping(value = "{applicationContractId}", produces = "application/json", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) + @PreAuthorize( "hasRole('ROLE_SUPER_ADMIN') || hasRole('ROLE_BENEFICIARY') || hasRole('ROLE_CONFIDI')") + ResponseEntity> updateApplicationContract(HttpServletRequest request, + @Parameter(description = "Application Contract ID", required = true) @PathVariable("applicationContractId") Long applicationContractId, @Parameter(description = "List of files to upload", required = true) + @RequestPart(required = true) List beneficiaryContractDocuments); + + @Operation(summary = "Api to get an application contract by id", + 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 = "{applicationContractId}", produces = "application/json") + ResponseEntity> getApplicationContractById(HttpServletRequest request,@Parameter(description = "The application contract id", required = true) @RequestParam(value = "id", required = true) Long id); + + @Operation(summary = "Api to get an application contract by application id", + 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 = "/application/{applicationId}", produces = "application/json") + ResponseEntity> getApplicationContractByApplicationId(HttpServletRequest request,@Parameter(description = "The application id", required = true) @RequestParam(value = "applicationId", required = true) Long applicationId); + + @Operation(summary = "Api to get an application contract by beneficiary user id", + 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 = "/user/{userId}", produces = "application/json") + ResponseEntity>> getApplicationContractByBeneficiaryUserId(HttpServletRequest request,@Parameter(description = "The user id", required = true) @RequestParam(value = "userId", required = true) Long userId); + +} diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/ApplicationContractApiController.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/ApplicationContractApiController.java new file mode 100644 index 00000000..4d5227e9 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/ApplicationContractApiController.java @@ -0,0 +1,86 @@ +package net.gepafin.tendermanagement.web.rest.api.impl; + +import jakarta.servlet.http.HttpServletRequest; +import net.gepafin.tendermanagement.config.Translator; +import net.gepafin.tendermanagement.constants.GepafinConstant; +import net.gepafin.tendermanagement.enums.UserActionContextEnum; +import net.gepafin.tendermanagement.enums.UserActionLogsEnum; +import net.gepafin.tendermanagement.model.request.ApplicationContractRequest; +import net.gepafin.tendermanagement.model.request.UserActionRequest; +import net.gepafin.tendermanagement.model.response.ApplicationContractResponse; +import net.gepafin.tendermanagement.model.util.Response; +import net.gepafin.tendermanagement.service.ApplicationContractService; +import net.gepafin.tendermanagement.util.LoggingUtil; +import net.gepafin.tendermanagement.web.rest.api.ApplicationContractApi; +import net.gepafin.tendermanagement.web.rest.api.errors.Status; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +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 java.util.List; + +@RestController +@RequestMapping("${openapi.gepafin.base-path:/v1/applicationContract}") +public class ApplicationContractApiController implements ApplicationContractApi { + + @Autowired + private LoggingUtil loggingUtil; + + @Autowired + private ApplicationContractService applicationContractService; + + @Override + public ResponseEntity> createApplicationContract(HttpServletRequest request, Long applicationId, List contractDocuments, ApplicationContractRequest applicationContractRequest) { + loggingUtil.logUserAction( + UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.INSERT).actionContext(UserActionContextEnum.CREATE_CONTRACT_FOR_APPLICATION).build()); + ApplicationContractResponse applicationContractResponse=applicationContractService.createApplicationContract(request,applicationId,contractDocuments,applicationContractRequest); + + return ResponseEntity.status(HttpStatus.OK) + .body(new Response<>(applicationContractResponse, Status.SUCCESS, Translator.toLocale(GepafinConstant.CREATE_APPLICATION_CONTRACT))); + + } + + @Override + public ResponseEntity> updateApplicationContract(HttpServletRequest request, Long applicationId, List beneficiaryContractDocuments) { + loggingUtil.logUserAction( + UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.UPDATE).actionContext(UserActionContextEnum.UPDATE_APPLICATION_CONTRACT).build()); + ApplicationContractResponse applicationContractResponse=applicationContractService.updateApplicationContract(request,applicationId,beneficiaryContractDocuments); + + return ResponseEntity.status(HttpStatus.OK) + .body(new Response<>(applicationContractResponse, Status.SUCCESS, Translator.toLocale(GepafinConstant.APPLICATION_CONTRACT_UPDATED))); + } + + @Override + public ResponseEntity> getApplicationContractById(HttpServletRequest request, Long id) { + loggingUtil.logUserAction( + UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.VIEW).actionContext(UserActionContextEnum.FETCH_APPLICATION_CONTRACT).build()); + ApplicationContractResponse applicationContractResponse=applicationContractService.getContractById(id); + + return ResponseEntity.status(HttpStatus.OK) + .body(new Response<>(applicationContractResponse, Status.SUCCESS, Translator.toLocale(GepafinConstant.APPLICATION_CONTRACT_FETCHED))); + } + + @Override + public ResponseEntity> getApplicationContractByApplicationId(HttpServletRequest request, Long applicationId) { + loggingUtil.logUserAction( + UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.VIEW).actionContext(UserActionContextEnum.FETCH_APPLICATION_CONTRACT_BY_APPLICATION_ID).build()); + ApplicationContractResponse applicationContractResponse=applicationContractService.getContractByApplicationId(applicationId); + + return ResponseEntity.status(HttpStatus.OK) + .body(new Response<>(applicationContractResponse, Status.SUCCESS, Translator.toLocale(GepafinConstant.APPLICATION_CONTRACT_FETCHED))); + } + + @Override + public ResponseEntity>> getApplicationContractByBeneficiaryUserId(HttpServletRequest request, Long beneficiaryUserId) { + loggingUtil.logUserAction( + UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.VIEW).actionContext(UserActionContextEnum.FETCH_APPLICATION_CONTRACT_BY_BENEFICIARY_USER_ID).build()); + List applicationContractResponse=applicationContractService.getContractByBeneficiaryUserId(beneficiaryUserId); + + return ResponseEntity.status(HttpStatus.OK) + .body(new Response<>(applicationContractResponse, Status.SUCCESS, Translator.toLocale(GepafinConstant.APPLICATION_CONTRACT_FETCHED))); + } + +} 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 a1698fc2..e96d0bf7 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 @@ -3100,4 +3100,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/db/dump/insert_notification_template_for_contract_upload.sql b/src/main/resources/db/dump/insert_notification_template_for_contract_upload.sql new file mode 100644 index 00000000..7100bc6a --- /dev/null +++ b/src/main/resources/db/dump/insert_notification_template_for_contract_upload.sql @@ -0,0 +1,2 @@ +INSERT INTO notification_type (notification_name,title, json_template,created_date,updated_date,is_deleted) VALUES +('CONTRACT_UPLOAD', 'Documento caricato per contratto','La richiesta in {{call_name}} con protocollo n. {{protocol_number}} ha caricato un documento per il contratto.','2025-11-04T15:16:26.472Z','2025-11-04T15:16:26.472Z','false'); \ No newline at end of file diff --git a/src/main/resources/message_en.properties b/src/main/resources/message_en.properties index c02deff6..48b7a1d6 100644 --- a/src/main/resources/message_en.properties +++ b/src/main/resources/message_en.properties @@ -416,5 +416,11 @@ pec.email.required=PEC email is required. application.technical.evaluation.rejected.success=Application changes to status application technical evaluation rejected successfully. invalid.email.json=Invalid email json. more.fields.required=Subject, reason, and motivation are required when rejecting the application. - - +create.application.contract=Application contract created successfully. +application.contract.not.found=Application contract not found. +application.contract.fetched=Application contract fetched successfully. +application.contract.updated=Application contract updated successfully. +files.required.for.contract=Files are required for contract. +application.contract.already.exist=Application contract already exist for this application. +application.not.approved=Application is not approved. +subject.body.required=Subject and body is required to create contract. diff --git a/src/main/resources/message_it.properties b/src/main/resources/message_it.properties index e18f529a..9a0f2724 100644 --- a/src/main/resources/message_it.properties +++ b/src/main/resources/message_it.properties @@ -407,3 +407,11 @@ pec.email.required=Obbligatorio l'indirizzo e-mail PEC. application.technical.evaluation.rejected.success=Lo stato dell'applicazione cambia: valutazione tecnica dell'applicazione rifiutata con successo. invalid.email.json=Codice email json non valido. more.fields.required=Per rifiutare la domanda sono richiesti oggetto, motivo e motivazione. +create.application.contract=Contratto di candidatura creato con successo. +application.contract.not.found=Contratto di candidatura non trovato. +application.contract.fetched=Contratto di candidatura recuperato con successo. +application.contract.updated=Contratto di candidatura aggiornato con successo. +files.required.for.contract=I file sono necessari per il contratto. +application.contract.already.exist=Il contratto di applicazione esiste gi per questa applicazione. +application.not.approved=La domanda non stata approvata. +subject.body.required=Per creare un contratto sono necessari oggetto e corpo. From fb3c50fe8f12d105d92bf80fdbad0af12ae9c7cb Mon Sep 17 00:00:00 2001 From: rajesh Date: Tue, 4 Nov 2025 20:12:06 +0530 Subject: [PATCH 61/75] Updated code --- .../web/rest/api/ApplicationContractApi.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/ApplicationContractApi.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/ApplicationContractApi.java index c81e9a2b..350aa2ac 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/ApplicationContractApi.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/ApplicationContractApi.java @@ -66,8 +66,8 @@ public interface ApplicationContractApi { @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 = "{applicationContractId}", produces = "application/json") - ResponseEntity> getApplicationContractById(HttpServletRequest request,@Parameter(description = "The application contract id", required = true) @RequestParam(value = "id", required = true) Long id); + @GetMapping(value = "{id}", produces = "application/json") + ResponseEntity> getApplicationContractById(HttpServletRequest request,@Parameter(description = "The application contract id", required = true) @PathVariable(value = "id", required = true) Long id); @Operation(summary = "Api to get an application contract by application id", responses = { @@ -78,7 +78,7 @@ public interface ApplicationContractApi { @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 = "/application/{applicationId}", produces = "application/json") + @GetMapping(value = "/application", produces = "application/json") ResponseEntity> getApplicationContractByApplicationId(HttpServletRequest request,@Parameter(description = "The application id", required = true) @RequestParam(value = "applicationId", required = true) Long applicationId); @Operation(summary = "Api to get an application contract by beneficiary user id", @@ -90,7 +90,7 @@ public interface ApplicationContractApi { @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 = "/user/{userId}", produces = "application/json") + @GetMapping(value = "/user", produces = "application/json") ResponseEntity>> getApplicationContractByBeneficiaryUserId(HttpServletRequest request,@Parameter(description = "The user id", required = true) @RequestParam(value = "userId", required = true) Long userId); } From 481a9742bd5ae9ca9899522680a44065fbf44d31 Mon Sep 17 00:00:00 2001 From: rajesh Date: Wed, 5 Nov 2025 12:35:05 +0530 Subject: [PATCH 62/75] Fixed user issue in contract --- .../tendermanagement/dao/ApplicationContractDao.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationContractDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationContractDao.java index e8e0a44d..52e29bd5 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationContractDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationContractDao.java @@ -14,6 +14,7 @@ import net.gepafin.tendermanagement.model.response.ApplicationContractResponse; import net.gepafin.tendermanagement.model.response.DocumentResponseBean; import net.gepafin.tendermanagement.repositories.ApplicationContractRepository; import net.gepafin.tendermanagement.repositories.ApplicationRepository; +import net.gepafin.tendermanagement.service.UserService; import net.gepafin.tendermanagement.util.DateTimeUtil; import net.gepafin.tendermanagement.util.LoggingUtil; import net.gepafin.tendermanagement.util.Utils; @@ -63,6 +64,9 @@ public class ApplicationContractDao { @Autowired private NotificationDao notificationDao; + @Autowired + private UserService userService; + public ApplicationContractResponse createApplicationContract(Long applicationId, List contractDocuments, ApplicationContractRequest applicationContractRequest, UserEntity user) { ApplicationEntity applicationEntity = applicationDao.validateApplication(applicationId); @@ -84,7 +88,8 @@ public class ApplicationContractDao { applicationRepository.save(applicationEntity); loggingUtil.addVersionHistory( VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplicationData).newData(applicationEntity).build()); - emailNotificationDao.sendEmailForApplicationContracted(applicationEntity, applicationContractEntity, user); + UserEntity userEntity = userService.validateUser(applicationEntity.getUserId()); + emailNotificationDao.sendEmailForApplicationContracted(applicationEntity, applicationContractEntity, userEntity); return createApplicationContractResponse(applicationContractEntity, documentResponseBeans, null); } From 2bb63cd90acd6441f4021559bbc66ecee23bcc84 Mon Sep 17 00:00:00 2001 From: rajesh Date: Wed, 5 Nov 2025 16:39:40 +0530 Subject: [PATCH 63/75] Fixed number format issue in pdf --- src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java b/src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java index 233ced7a..cf3419e3 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java @@ -404,7 +404,8 @@ public class PdfDao { calculateValue(key, fieldValue, formulaTypeMap, columnSums); } String fieldLabel = stateFieldMap.getOrDefault(key, ""); - if(Boolean.FALSE.equals(fieldLabel.equalsIgnoreCase("Anno"))) { + + if(Boolean.FALSE.equals(fieldLabel.equalsIgnoreCase("Anno")) && Boolean.TRUE.equals(GepafinConstant.NUMERIC.equalsIgnoreCase(fieldTypeMap.get(key)))) { if (Boolean.TRUE.equals(Utils.isNumeric(fieldValue))) { fieldValue = Utils.convertToItalianFormat(fieldValue); } From 38fb338cb2eba2f80cce7c07f017249f9f73bf44 Mon Sep 17 00:00:00 2001 From: rajesh Date: Wed, 5 Nov 2025 17:46:58 +0530 Subject: [PATCH 64/75] Added contract object to response of assigned application pagination API --- .../dao/ApplicationContractDao.java | 29 +++++++++++++------ .../dao/AssignedApplicationsDao.java | 6 ++++ .../enums/AssignedApplicationEnum.java | 6 +++- .../AssignedApplicationViewResponse.java | 1 + 4 files changed, 32 insertions(+), 10 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationContractDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationContractDao.java index 52e29bd5..2f31d2dd 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationContractDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationContractDao.java @@ -3,10 +3,7 @@ package net.gepafin.tendermanagement.dao; import jakarta.servlet.http.HttpServletRequest; import net.gepafin.tendermanagement.config.Translator; import net.gepafin.tendermanagement.constants.GepafinConstant; -import net.gepafin.tendermanagement.entities.ApplicationContractEntity; -import net.gepafin.tendermanagement.entities.ApplicationEntity; -import net.gepafin.tendermanagement.entities.ApplicationEvaluationEntity; -import net.gepafin.tendermanagement.entities.UserEntity; +import net.gepafin.tendermanagement.entities.*; import net.gepafin.tendermanagement.enums.*; import net.gepafin.tendermanagement.model.request.ApplicationContractRequest; import net.gepafin.tendermanagement.model.request.VersionHistoryRequest; @@ -14,6 +11,7 @@ import net.gepafin.tendermanagement.model.response.ApplicationContractResponse; import net.gepafin.tendermanagement.model.response.DocumentResponseBean; import net.gepafin.tendermanagement.repositories.ApplicationContractRepository; import net.gepafin.tendermanagement.repositories.ApplicationRepository; +import net.gepafin.tendermanagement.repositories.AssignedApplicationsRepository; import net.gepafin.tendermanagement.service.UserService; import net.gepafin.tendermanagement.util.DateTimeUtil; import net.gepafin.tendermanagement.util.LoggingUtil; @@ -25,10 +23,7 @@ import org.springframework.stereotype.Component; import org.springframework.web.multipart.MultipartFile; import java.time.LocalDateTime; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.stream.Collectors; @Component @@ -67,9 +62,14 @@ public class ApplicationContractDao { @Autowired private UserService userService; + @Autowired + private AssignedApplicationsRepository assignedApplicationsRepository; + public ApplicationContractResponse createApplicationContract(Long applicationId, List contractDocuments, ApplicationContractRequest applicationContractRequest, UserEntity user) { ApplicationEntity applicationEntity = applicationDao.validateApplication(applicationId); - + Optional optionalAssignedApplicationsEntity=assignedApplicationsRepository.findByApplicationIdAndIsDeletedFalse(applicationEntity.getId()); + AssignedApplicationsEntity assignedApplicationsEntity=optionalAssignedApplicationsEntity.get(); + AssignedApplicationsEntity oldAssignedApplicationEntity=Utils.getClonedEntityForData(assignedApplicationsEntity); if (Boolean.FALSE.equals(applicationEntity.getStatus().equals(ApplicationStatusTypeEnum.APPROVED.getValue()))) { throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.APPLICATION_NOT_APPROVED)); } @@ -85,9 +85,13 @@ public class ApplicationContractDao { loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.INSERT).oldData(null).newData(applicationContractEntity).build()); List documentResponseBeans = setContractDocuments(contractDocuments, user, applicationContractEntity); applicationEntity.setStatus(ApplicationStatusTypeEnum.AWAITING_CONTRACT.getValue()); + assignedApplicationsEntity.setStatus(AssignedApplicationEnum.AWAITING_CONTRACT.getValue()); applicationRepository.save(applicationEntity); + assignedApplicationsRepository.save(assignedApplicationsEntity); loggingUtil.addVersionHistory( VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplicationData).newData(applicationEntity).build()); + loggingUtil.addVersionHistory( + VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldAssignedApplicationEntity).newData(assignedApplicationsEntity).build()); UserEntity userEntity = userService.validateUser(applicationEntity.getUserId()); emailNotificationDao.sendEmailForApplicationContracted(applicationEntity, applicationContractEntity, userEntity); return createApplicationContractResponse(applicationContractEntity, documentResponseBeans, null); @@ -152,11 +156,18 @@ public class ApplicationContractDao { VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplicationContract).newData(applicationContractEntity).build()); ApplicationEntity applicationEntity = applicationDao.validateApplication(applicationContractEntity.getApplicationId()); ApplicationEntity oldApplicationData = Utils.getClonedEntityForData(applicationEntity); + Optional optionalAssignedApplicationsEntity=assignedApplicationsRepository.findByApplicationIdAndIsDeletedFalse(applicationEntity.getId()); + AssignedApplicationsEntity assignedApplicationsEntity=optionalAssignedApplicationsEntity.get(); + AssignedApplicationsEntity oldAssignedApplicationEntity=Utils.getClonedEntityForData(assignedApplicationsEntity); ApplicationEvaluationEntity applicationEvaluationEntity = applicationEvaluationDao.validateApplicationEvaluation(applicationEntity.getApplicationEvaluationId()); applicationEntity.setStatus(ApplicationStatusTypeEnum.CONTRACT_SIGNED.getValue()); + assignedApplicationsEntity.setStatus(AssignedApplicationEnum.CONTRACT_SIGNED.getValue()); applicationRepository.save(applicationEntity); + assignedApplicationsRepository.save(assignedApplicationsEntity); loggingUtil.addVersionHistory( VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplicationData).newData(applicationEntity).build()); + loggingUtil.addVersionHistory( + VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldAssignedApplicationEntity).newData(assignedApplicationsEntity).build()); Map placeHolders = new HashMap<>(); placeHolders.put("{{call_name}}", applicationEntity.getCall().getName()); String protocolNumber = applicationEntity.getProtocol().getExternalProtocolNumber(); diff --git a/src/main/java/net/gepafin/tendermanagement/dao/AssignedApplicationsDao.java b/src/main/java/net/gepafin/tendermanagement/dao/AssignedApplicationsDao.java index 1a3c2e05..87c4dafe 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/AssignedApplicationsDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/AssignedApplicationsDao.java @@ -14,6 +14,7 @@ import net.gepafin.tendermanagement.model.request.ApplicationEvaluationRequest; import net.gepafin.tendermanagement.model.request.AssignedApplicationsRequest; import net.gepafin.tendermanagement.model.request.UpdateAssignedApplicationRequest; import net.gepafin.tendermanagement.model.request.VersionHistoryRequest; +import net.gepafin.tendermanagement.model.response.ApplicationContractResponse; import net.gepafin.tendermanagement.model.response.AssignedApplicationViewResponse; import net.gepafin.tendermanagement.model.response.AssignedApplicationsResponse; import net.gepafin.tendermanagement.model.response.PageableResponseBean; @@ -82,6 +83,9 @@ public class AssignedApplicationsDao { @Autowired private AssignedApplicationsViewRepository assignedApplicationsViewRepository; + @Autowired + private ApplicationContractDao applicationContractDao; + public AssignedApplicationsResponse createAssignedApplications(Long applicationId, Long userId, UserEntity assignedByUser, AssignedApplicationsRequest assignedApplicationsRequest) { log.info("Assigning application to pre-Instructor with details: {}", applicationId, userId); @@ -492,6 +496,8 @@ public class AssignedApplicationsDao { response.setUpdatedDate(view.getUpdatedDate()); response.setEmailSendResponse(view.getEmailSendResponse()); response.setAssignedUserName(view.getAssignedUserName()); + ApplicationContractResponse applicationContractResponse=applicationContractDao.getContractByApplicationId(response.getApplicationId()); + response.setContract(applicationContractResponse); return response; } diff --git a/src/main/java/net/gepafin/tendermanagement/enums/AssignedApplicationEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/AssignedApplicationEnum.java index be3f6b1a..c0206637 100644 --- a/src/main/java/net/gepafin/tendermanagement/enums/AssignedApplicationEnum.java +++ b/src/main/java/net/gepafin/tendermanagement/enums/AssignedApplicationEnum.java @@ -8,7 +8,11 @@ public enum AssignedApplicationEnum { AWAITING("AWAITING"), - CLOSE("CLOSE"); + CLOSE("CLOSE"), + + AWAITING_CONTRACT("AWAITING_CONTRACT"), + + CONTRACT_SIGNED("CONTRACT_SIGNED"); private final String value; diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/AssignedApplicationViewResponse.java b/src/main/java/net/gepafin/tendermanagement/model/response/AssignedApplicationViewResponse.java index 22f00b0d..49271385 100644 --- a/src/main/java/net/gepafin/tendermanagement/model/response/AssignedApplicationViewResponse.java +++ b/src/main/java/net/gepafin/tendermanagement/model/response/AssignedApplicationViewResponse.java @@ -23,6 +23,7 @@ public class AssignedApplicationViewResponse extends BaseBean { private String companyName; private String assignedUserName; private List emailSendResponse; + private ApplicationContractResponse contract; } From 2d6de7cf6d9af81980b2ca180bf08e7380bfdce2 Mon Sep 17 00:00:00 2001 From: rajesh Date: Wed, 5 Nov 2025 19:28:22 +0530 Subject: [PATCH 65/75] Added call name and application id in contract API response --- .../dao/ApplicationContractDao.java | 22 ++++++++++++------- .../response/ApplicationContractResponse.java | 4 ++++ 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationContractDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationContractDao.java index 2f31d2dd..704e7b7e 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationContractDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationContractDao.java @@ -94,10 +94,10 @@ public class ApplicationContractDao { VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldAssignedApplicationEntity).newData(assignedApplicationsEntity).build()); UserEntity userEntity = userService.validateUser(applicationEntity.getUserId()); emailNotificationDao.sendEmailForApplicationContracted(applicationEntity, applicationContractEntity, userEntity); - return createApplicationContractResponse(applicationContractEntity, documentResponseBeans, null); + return createApplicationContractResponse(applicationContractEntity, documentResponseBeans, null,applicationEntity.getCall().getName()); } - private ApplicationContractResponse createApplicationContractResponse(ApplicationContractEntity applicationContractEntity, List instructorDocuments, List beneficiaryDocuments) { + private ApplicationContractResponse createApplicationContractResponse(ApplicationContractEntity applicationContractEntity, List instructorDocuments, List beneficiaryDocuments,String callName) { ApplicationContractResponse applicationContractResponse = new ApplicationContractResponse(); applicationContractResponse.setId(applicationContractEntity.getId()); applicationContractResponse.setText(applicationContractEntity.getText()); @@ -108,6 +108,8 @@ public class ApplicationContractDao { applicationContractResponse.setBeneficiaryDocuments(beneficiaryDocuments); applicationContractResponse.setCompletionDate(applicationContractEntity.getCompletionDate()); applicationContractResponse.setBeneficiaryUserId(applicationContractEntity.getBeneficiaryUserId()); + applicationContractResponse.setApplicationId(applicationContractEntity.getApplicationId()); + applicationContractResponse.setCallName(callName); return applicationContractResponse; } @@ -177,7 +179,7 @@ public class ApplicationContractDao { placeHolders.put("{{protocol_number}}", protocolNumber); notificationDao.sendNotificationToInstructor(placeHolders, applicationEvaluationEntity, NotificationTypeEnum.CONTRACT_UPLOAD); - return createApplicationContractResponse(applicationContractEntity, documentResponseBeans, beneficiaryContractDocuments1); + return createApplicationContractResponse(applicationContractEntity, documentResponseBeans, beneficiaryContractDocuments1,applicationEntity.getCall().getName()); } public ApplicationContractEntity validateApplicationContract(Long applicationContractId) { @@ -203,21 +205,24 @@ public class ApplicationContractDao { public ApplicationContractResponse getContractById(Long contractId) { ApplicationContractEntity applicationContractEntity = validateApplicationContract(contractId); - return createApplicationContractResponseFromEntity(applicationContractEntity); + ApplicationEntity applicationEntity = applicationDao.validateApplication(applicationContractEntity.getApplicationId()); + return createApplicationContractResponseFromEntity(applicationContractEntity,applicationEntity.getCall().getName()); } - private ApplicationContractResponse createApplicationContractResponseFromEntity(ApplicationContractEntity applicationContractEntity) { + private ApplicationContractResponse createApplicationContractResponseFromEntity(ApplicationContractEntity applicationContractEntity,String callName) { List instructorDocuments = applicationAmendmentRequestDao.getDocumentResponseBean(applicationContractEntity.getInstructorDocument()); List beneficiaryDocuments = applicationAmendmentRequestDao.getDocumentResponseBean(applicationContractEntity.getBeneficiaryDocument()); - return createApplicationContractResponse(applicationContractEntity, instructorDocuments, beneficiaryDocuments); + return createApplicationContractResponse(applicationContractEntity, instructorDocuments, beneficiaryDocuments,callName); } public ApplicationContractResponse getContractByApplicationId(Long applicationId) { ApplicationContractEntity applicationContractEntity = applicationContractRepository.findByApplicationIdAndIsDeletedFalse(applicationId); + ApplicationEntity applicationEntity = applicationDao.validateApplication(applicationContractEntity.getApplicationId()); + if (applicationContractEntity == null) { return null; } - return createApplicationContractResponseFromEntity(applicationContractEntity); + return createApplicationContractResponseFromEntity(applicationContractEntity,applicationEntity.getCall().getName()); } public List getContractByBeneficiaryUserId(UserEntity user) { @@ -228,7 +233,8 @@ public class ApplicationContractDao { } List applicationContractResponses = new ArrayList<>(); for (ApplicationContractEntity applicationContractEntity : applicationContractEntities) { - ApplicationContractResponse applicationContractResponse = createApplicationContractResponseFromEntity(applicationContractEntity); + ApplicationEntity applicationEntity = applicationDao.validateApplication(applicationContractEntity.getApplicationId()); + ApplicationContractResponse applicationContractResponse = createApplicationContractResponseFromEntity(applicationContractEntity,applicationEntity.getCall().getName()); applicationContractResponses.add(applicationContractResponse); } return applicationContractResponses; diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationContractResponse.java b/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationContractResponse.java index d3d19dac..a90d1204 100644 --- a/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationContractResponse.java +++ b/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationContractResponse.java @@ -27,4 +27,8 @@ public class ApplicationContractResponse { private LocalDateTime completionDate; + private Long applicationId; + + private String callName; + } From 6600c5b319899c8d6eefda7df3f4077cbfa8a954 Mon Sep 17 00:00:00 2001 From: rajesh Date: Wed, 5 Nov 2025 20:20:40 +0530 Subject: [PATCH 66/75] Updated code --- .../gepafin/tendermanagement/dao/ApplicationContractDao.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationContractDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationContractDao.java index 704e7b7e..44b7013a 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationContractDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationContractDao.java @@ -217,11 +217,11 @@ public class ApplicationContractDao { public ApplicationContractResponse getContractByApplicationId(Long applicationId) { ApplicationContractEntity applicationContractEntity = applicationContractRepository.findByApplicationIdAndIsDeletedFalse(applicationId); - ApplicationEntity applicationEntity = applicationDao.validateApplication(applicationContractEntity.getApplicationId()); - if (applicationContractEntity == null) { return null; } + + ApplicationEntity applicationEntity = applicationDao.validateApplication(applicationContractEntity.getApplicationId()); return createApplicationContractResponseFromEntity(applicationContractEntity,applicationEntity.getCall().getName()); } From c8ce9acee8d0530e0f03821a88828674d1aa3fdb Mon Sep 17 00:00:00 2001 From: rajesh Date: Thu, 6 Nov 2025 12:26:11 +0530 Subject: [PATCH 67/75] Added contract object in evaluation API --- .../tendermanagement/dao/ApplicationEvaluationDao.java | 7 +++++++ .../model/response/ApplicationEvaluationFormResponse.java | 2 ++ .../model/response/ApplicationEvaluationResponse.java | 1 + 3 files changed, 10 insertions(+) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java index 430e28da..121cd15e 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java @@ -157,6 +157,9 @@ public class ApplicationEvaluationDao { @Autowired private ApplicationSignedDocumentRepository applicationSignedDocumentRepository; + @Autowired + private ApplicationContractDao applicationContractDao; + private ApplicationEvaluationEntity convertToEntity(UserEntity user, ApplicationEvaluationRequest req, Long assignedApplciationId) { ApplicationEvaluationEntity entity = new ApplicationEvaluationEntity(); @@ -1193,6 +1196,8 @@ public class ApplicationEvaluationDao { ApplicationEvaluationResponse applicationEvaluationResponse = convertToResponse(entity); applicationEvaluationResponse.setSignedDocument(getApplicationSignedDocument(entity)); applicationEvaluationResponse.setEmailSendResponse(entity.getEmailSendResponse()); + ApplicationContractResponse applicationContractResponse=applicationContractDao.getContractByApplicationId(applicationID); + applicationEvaluationResponse.setContract(applicationContractResponse); return applicationEvaluationResponse; } public List prepareEvaluationDocumentBeanList(ApplicationEvaluationEntity entity) { @@ -2423,6 +2428,8 @@ public class ApplicationEvaluationDao { response.setCompanyCodiceAteco(company.getCodiceAteco()); response.setSignedDocument(getApplicationSignedDocument(evaluationEntity)); response.setEmailSendResponse(evaluationEntity.getEmailSendResponse()); + ApplicationContractResponse applicationContractResponse=applicationContractDao.getContractByApplicationId(evaluationEntity.getApplicationId()); + response.setContract(applicationContractResponse); return response; } diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationEvaluationFormResponse.java b/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationEvaluationFormResponse.java index 84cf4989..2e18339a 100644 --- a/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationEvaluationFormResponse.java +++ b/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationEvaluationFormResponse.java @@ -50,5 +50,7 @@ public class ApplicationEvaluationFormResponse { private String companyCodiceAteco; private List emailSendResponse; private ApplicationSignedDocumentResponse signedDocument; + private ApplicationContractResponse contract; + } diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationEvaluationResponse.java b/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationEvaluationResponse.java index 33b58062..742edae9 100644 --- a/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationEvaluationResponse.java +++ b/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationEvaluationResponse.java @@ -52,5 +52,6 @@ public class ApplicationEvaluationResponse { private List emailSendResponse; private List rejectedDocument; private ApplicationSignedDocumentResponse signedDocument; + private ApplicationContractResponse contract; } From 98cdda457da41148d6d25c36fe42838534e94455 Mon Sep 17 00:00:00 2001 From: rajesh Date: Fri, 7 Nov 2025 18:10:43 +0530 Subject: [PATCH 68/75] Created director user and get API for email log --- .../constants/GepafinConstant.java | 2 + .../tendermanagement/dao/EmailLogDao.java | 5 +- .../tendermanagement/dao/PecMailDao.java | 142 ++++++++++++++++++ .../enums/StatusTypeEnum.java | 2 +- .../enums/UserActionContextEnum.java | 5 +- .../model/response/EmailLogResponse.java | 12 ++ .../model/response/PecEmailLogResponse.java | 30 ++++ .../model/response/PecMailResponse.java | 28 ++++ .../repositories/EmailLogRepository.java | 5 + .../service/PecMailService.java | 16 ++ .../service/impl/PecMailSerivceImpl.java | 33 ++++ .../web/rest/api/PecMailApi.java | 56 +++++++ .../web/rest/api/impl/PecMailController.java | 69 +++++++++ .../db/changelog/db.changelog-1.0.0.xml | 29 ++++ src/main/resources/message_en.properties | 1 + src/main/resources/message_it.properties | 1 + 16 files changed, 430 insertions(+), 6 deletions(-) create mode 100644 src/main/java/net/gepafin/tendermanagement/dao/PecMailDao.java create mode 100644 src/main/java/net/gepafin/tendermanagement/model/response/EmailLogResponse.java create mode 100644 src/main/java/net/gepafin/tendermanagement/model/response/PecEmailLogResponse.java create mode 100644 src/main/java/net/gepafin/tendermanagement/model/response/PecMailResponse.java create mode 100644 src/main/java/net/gepafin/tendermanagement/service/PecMailService.java create mode 100644 src/main/java/net/gepafin/tendermanagement/service/impl/PecMailSerivceImpl.java create mode 100644 src/main/java/net/gepafin/tendermanagement/web/rest/api/PecMailApi.java create mode 100644 src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/PecMailController.java diff --git a/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java b/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java index bf25387c..452ecb50 100644 --- a/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java +++ b/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java @@ -631,6 +631,8 @@ public class GepafinConstant { public static final String APPLICATION_CONTRACT_ALREADY_EXIST="application.contract.already.exist"; public static final String APPLICATION_NOT_APPROVED="application.not.approved"; public static final String SUBJECT_AND_BODY_REQUIRED="subject.body.required"; + public static final String MAIL_SENT_SUCCESSFULLY="mail.send.successfully"; + public static final String EMAIL_LOG_FETCHED="email.log.fetched"; } diff --git a/src/main/java/net/gepafin/tendermanagement/dao/EmailLogDao.java b/src/main/java/net/gepafin/tendermanagement/dao/EmailLogDao.java index d95978fd..747c9e83 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/EmailLogDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/EmailLogDao.java @@ -3,10 +3,7 @@ package net.gepafin.tendermanagement.dao; import jakarta.servlet.http.HttpServletRequest; import net.gepafin.tendermanagement.constants.GepafinConstant; import net.gepafin.tendermanagement.entities.EmailLogEntity; -import net.gepafin.tendermanagement.enums.EmailScenarioTypeEnum; -import net.gepafin.tendermanagement.enums.EmailEntityTypeEnum; -import net.gepafin.tendermanagement.enums.RecipientTypeEnum; -import net.gepafin.tendermanagement.enums.VersionActionTypeEnum; +import net.gepafin.tendermanagement.enums.*; import net.gepafin.tendermanagement.model.request.EmailLogRequest; import net.gepafin.tendermanagement.model.request.VersionHistoryRequest; import net.gepafin.tendermanagement.repositories.EmailLogRepository; diff --git a/src/main/java/net/gepafin/tendermanagement/dao/PecMailDao.java b/src/main/java/net/gepafin/tendermanagement/dao/PecMailDao.java new file mode 100644 index 00000000..f24c6be8 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/dao/PecMailDao.java @@ -0,0 +1,142 @@ +package net.gepafin.tendermanagement.dao; + +import jakarta.servlet.http.HttpServletRequest; +import liquibase.util.Validate; +import lombok.extern.log4j.Log4j2; +import net.gepafin.tendermanagement.config.Translator; +import net.gepafin.tendermanagement.constants.GepafinConstant; +import net.gepafin.tendermanagement.entities.*; +import net.gepafin.tendermanagement.enums.EmailServiceTypeEnum; +import net.gepafin.tendermanagement.enums.StatusTypeEnum; +import net.gepafin.tendermanagement.model.response.EmailLogResponse; +import net.gepafin.tendermanagement.model.response.PecEmailLogResponse; +import net.gepafin.tendermanagement.model.response.PecMailResponse; +import net.gepafin.tendermanagement.repositories.EmailLogRepository; +import net.gepafin.tendermanagement.repositories.UserActionsRepository; +import net.gepafin.tendermanagement.service.ApplicationService; +import net.gepafin.tendermanagement.service.CallService; +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.checkerframework.checker.units.qual.A; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.List; + +@Component +@Log4j2 +public class PecMailDao { + + @Autowired + private Validator validator; + + @Autowired + private UserActionsRepository userActionsRepository; + + @Autowired + private EmailLogRepository emailLogRepository; + + @Autowired + private CallService callService; + + @Autowired + private EmailNotificationDao emailNotificationDao; + + @Autowired + private ApplicationService applicationService; + + + public PecMailResponse sendPecMail(HttpServletRequest request, List userActionIds) { + + for (Long userActionId: userActionIds) { + List emailLogs = getEmailLogEntities(request, userActionId); + for (EmailLogEntity log : emailLogs) { + List recipients = Utils.commaSeparatedStringToList(log.getRecipientEmails()); + CallEntity call = callService.validateCall(log.getCallId()); + emailNotificationDao.sendMail( + call.getHub().getId(), + log.getEmailSubject(), + log.getEmailBody(), + recipients, + null + ); + + } + } + return null; + } + + private List getEmailLogEntities(HttpServletRequest request, Long userActionId) { + UserActionEntity userActionEntity = userActionsRepository.findUserActionByIdAndIsDeletedFalse(userActionId); + if (userActionEntity == null) { + throw new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.USER_ACTION_ID_NOT_FOUND)); + } + validator.validateHubId(request, userActionEntity.getHubId()); + + List emailLogs = emailLogRepository.findByUserActionIdAndEmailServiceTypeAndSendStatus(userActionId, EmailServiceTypeEnum.PEC_SERVICE.getValue(), StatusTypeEnum.PENDING.getValue()); + + if (emailLogs.isEmpty()) { + log.info("No emails found for given userActionId: {}", userActionId); + throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.NO_EMAIL_LOG_FOUND)); + } + return emailLogs; + } + + public List getEmailLogByUserActionId(HttpServletRequest request,Long userActionId){ + List emailLogs = getEmailLogEntities(request, userActionId); + ApplicationEntity applicationEntity=applicationService.validateApplication(emailLogs.get(0).getApplicationId()); + String callName=applicationEntity.getCall().getName(); + List pecEmailLogResponses=new ArrayList<>(); + for(EmailLogEntity emailLogEntity:emailLogs) { + PecEmailLogResponse pecEmailLogResponse = createPecEmailLogResponse(userActionId, emailLogEntity, callName); + pecEmailLogResponses.add(pecEmailLogResponse); + } + return pecEmailLogResponses; + } + + private PecEmailLogResponse createPecEmailLogResponse(Long userActionId, EmailLogEntity emailLogEntity, String callName) { + PecEmailLogResponse pecEmailLogResponse = new PecEmailLogResponse(); + pecEmailLogResponse.setId(emailLogEntity.getId()); + pecEmailLogResponse.setUserActionId(userActionId); + pecEmailLogResponse.setUserId(emailLogEntity.getUserId()); + pecEmailLogResponse.setApplicationId(emailLogEntity.getApplicationId()); + pecEmailLogResponse.setCallName(callName); + EmailLogResponse emailLogResponse=new EmailLogResponse(); + emailLogResponse.setRecipientId(emailLogEntity.getRecipientId()); + emailLogResponse.setRecipientType(emailLogEntity.getRecipientType()); + pecEmailLogResponse.setEmailLogs(emailLogResponse); + pecEmailLogResponse.setType(emailLogEntity.getEmailType()); + pecEmailLogResponse.setSubject(emailLogEntity.getEmailSubject()); + pecEmailLogResponse.setHtmlContent(emailLogEntity.getEmailBody()); + pecEmailLogResponse.setCallId(emailLogEntity.getCallId()); + return pecEmailLogResponse; + } + private PecMailResponse createPecMailResponse(Long userActionId, EmailLogEntity emailLogEntity, String callName) { + PecMailResponse pecMailResponse = new PecMailResponse(); + pecMailResponse.setId(emailLogEntity.getId()); + pecMailResponse.setUserActionId(userActionId); + pecMailResponse.setUserId(emailLogEntity.getUserId()); + pecMailResponse.setApplicationId(emailLogEntity.getApplicationId()); + pecMailResponse.setCallName(callName); + pecMailResponse.setType(emailLogEntity.getEmailType()); + pecMailResponse.setSubject(emailLogEntity.getEmailSubject()); + pecMailResponse.setHtmlContent(emailLogEntity.getEmailBody()); + pecMailResponse.setCallId(emailLogEntity.getCallId()); + return pecMailResponse; + } + public List getAllEmailLogs(HttpServletRequest request) { + List emailLogs=emailLogRepository.findPendingPECEmailLogs(); + List pecMailResponses=new ArrayList<>(); + for (EmailLogEntity emailLogEntity: emailLogs){ + ApplicationEntity applicationEntity=applicationService.validateApplication(emailLogEntity.getApplicationId()); + String callName=applicationEntity.getCall().getName(); + PecMailResponse pecMailResponse=createPecMailResponse(emailLogEntity.getUserAction().getId(),emailLogEntity,callName); + pecMailResponses.add(pecMailResponse); + } + return pecMailResponses; + } +} diff --git a/src/main/java/net/gepafin/tendermanagement/enums/StatusTypeEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/StatusTypeEnum.java index dc7c11d5..738a6a17 100644 --- a/src/main/java/net/gepafin/tendermanagement/enums/StatusTypeEnum.java +++ b/src/main/java/net/gepafin/tendermanagement/enums/StatusTypeEnum.java @@ -3,7 +3,7 @@ package net.gepafin.tendermanagement.enums; import com.fasterxml.jackson.annotation.JsonValue; public enum StatusTypeEnum { - + PENDING ("PENDING"), SUCCESS ("SUCCESS"), FAILED("FAILED"); diff --git a/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java index 98aca8cf..9401834e 100644 --- a/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java +++ b/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java @@ -229,7 +229,10 @@ public enum UserActionContextEnum { UPDATE_APPLICATION_CONTRACT("UPDATE_APPLICATION_CONTRACT"), FETCH_APPLICATION_CONTRACT("FETCH_APPLICATION_CONTRACT"), FETCH_APPLICATION_CONTRACT_BY_APPLICATION_ID("FETCH_APPLICATION_CONTRACT_BY_APPLICATION_ID"), - FETCH_APPLICATION_CONTRACT_BY_BENEFICIARY_USER_ID("FETCH_APPLICATION_CONTRACT_BY_BENEFICIARY_USER_ID"); + FETCH_APPLICATION_CONTRACT_BY_BENEFICIARY_USER_ID("FETCH_APPLICATION_CONTRACT_BY_BENEFICIARY_USER_ID"), + SEND_PEC_MAIL("SEND_PEC_MAIL"), + FETCH_EMAIL_LOG("FETCH_EMAIL_LOG"), + FETCH_ALL_EMAIL_LOG("FETCH_ALL_EMAIL_LOG"); private final String value; diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/EmailLogResponse.java b/src/main/java/net/gepafin/tendermanagement/model/response/EmailLogResponse.java new file mode 100644 index 00000000..c6b4ab77 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/model/response/EmailLogResponse.java @@ -0,0 +1,12 @@ +package net.gepafin.tendermanagement.model.response; + +import lombok.Data; + +@Data +public class EmailLogResponse { + + private String recipientType; + + private Long recipientId; + +} diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/PecEmailLogResponse.java b/src/main/java/net/gepafin/tendermanagement/model/response/PecEmailLogResponse.java new file mode 100644 index 00000000..6b0ada2f --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/model/response/PecEmailLogResponse.java @@ -0,0 +1,30 @@ +package net.gepafin.tendermanagement.model.response; + +import lombok.Data; + +import java.util.List; + +@Data +public class PecEmailLogResponse { + + private Long id; + + private Long userActionId; + + private Long userId; + + private Long applicationId; + + private String callName; + + private EmailLogResponse emailLogs; + + private String type; + + private String subject; + + private String htmlContent; + + private Long callId; + +} diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/PecMailResponse.java b/src/main/java/net/gepafin/tendermanagement/model/response/PecMailResponse.java new file mode 100644 index 00000000..b613772d --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/model/response/PecMailResponse.java @@ -0,0 +1,28 @@ +package net.gepafin.tendermanagement.model.response; + +import lombok.Data; + +import java.util.List; + +@Data +public class PecMailResponse { + + private Long id; + + private Long userActionId; + + private Long userId; + + private Long applicationId; + + private String callName; + + private String type; + + private String subject; + + private String htmlContent; + + private Long callId; + +} diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/EmailLogRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/EmailLogRepository.java index 9d9e26e5..0d6a2202 100644 --- a/src/main/java/net/gepafin/tendermanagement/repositories/EmailLogRepository.java +++ b/src/main/java/net/gepafin/tendermanagement/repositories/EmailLogRepository.java @@ -3,6 +3,7 @@ package net.gepafin.tendermanagement.repositories; import net.gepafin.tendermanagement.entities.EmailLogEntity; import net.gepafin.tendermanagement.entities.UserEntity; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; import java.util.List; import java.util.Optional; @@ -23,6 +24,10 @@ public interface EmailLogRepository extends JpaRepository { String sendStatus ); + @Query(value = """ + SELECT DISTINCT ON (user_action_id) * FROM email_log WHERE send_status = 'PENDING' AND is_deleted = false AND email_service_type = 'PEC_SERVICE' """, nativeQuery = true) + List findPendingPECEmailLogs(); + } diff --git a/src/main/java/net/gepafin/tendermanagement/service/PecMailService.java b/src/main/java/net/gepafin/tendermanagement/service/PecMailService.java new file mode 100644 index 00000000..2d7dbd30 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/service/PecMailService.java @@ -0,0 +1,16 @@ +package net.gepafin.tendermanagement.service; + +import jakarta.servlet.http.HttpServletRequest; +import net.gepafin.tendermanagement.model.response.PecEmailLogResponse; +import net.gepafin.tendermanagement.model.response.PecMailResponse; + +import java.util.List; + +public interface PecMailService { + + public PecMailResponse sendPecMail(HttpServletRequest request, List userActionIds); + + public List getEmailLogByUserActionId(HttpServletRequest request, Long userActionId); + + public List getAllEmailLogs(HttpServletRequest request); +} diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/PecMailSerivceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/PecMailSerivceImpl.java new file mode 100644 index 00000000..507923be --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/PecMailSerivceImpl.java @@ -0,0 +1,33 @@ +package net.gepafin.tendermanagement.service.impl; + +import jakarta.servlet.http.HttpServletRequest; +import net.gepafin.tendermanagement.dao.PecMailDao; +import net.gepafin.tendermanagement.model.response.PecEmailLogResponse; +import net.gepafin.tendermanagement.model.response.PecMailResponse; +import net.gepafin.tendermanagement.service.PecMailService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +public class PecMailSerivceImpl implements PecMailService { + + @Autowired + private PecMailDao pecMailDao; + + @Override + public PecMailResponse sendPecMail(HttpServletRequest request, List userActionIds) { + return pecMailDao.sendPecMail(request,userActionIds); + } + + @Override + public List getEmailLogByUserActionId(HttpServletRequest request, Long userActionId) { + return pecMailDao.getEmailLogByUserActionId(request,userActionId); + } + + @Override + public List getAllEmailLogs(HttpServletRequest request) { + return pecMailDao.getAllEmailLogs(request); + } +} diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/PecMailApi.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/PecMailApi.java new file mode 100644 index 00000000..34315491 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/PecMailApi.java @@ -0,0 +1,56 @@ +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.model.request.NotificationReq; +import net.gepafin.tendermanagement.model.response.NotificationResponse; +import net.gepafin.tendermanagement.model.response.PecEmailLogResponse; +import net.gepafin.tendermanagement.model.response.PecMailResponse; +import net.gepafin.tendermanagement.model.util.Response; +import net.gepafin.tendermanagement.web.rest.api.errors.ErrorConstants; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +public interface PecMailApi { + + @Operation(summary = "Api to send mail from pec.", 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 = "/userAction", produces = "application/json") + ResponseEntity> sendPecMail(HttpServletRequest request, + @Parameter(description = "The user action id", required = true) @RequestParam("userActionIds") List userActionIds); + + + @Operation(summary = "Api to get email log by user action id", 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 = "/userAction/{userActionId}", produces = "application/json") + ResponseEntity>> getEmailLogByUserActionId(HttpServletRequest request, + @Parameter(description = "The user action id", required = true) @PathVariable("userActionId") Long userActionId); + + @Operation(summary = "Api to get all email logs", 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 = "",produces = "application/json") + ResponseEntity>> getAllEmailLogs(HttpServletRequest request); + +} diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/PecMailController.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/PecMailController.java new file mode 100644 index 00000000..ca3c7c35 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/PecMailController.java @@ -0,0 +1,69 @@ +package net.gepafin.tendermanagement.web.rest.api.impl; + +import jakarta.servlet.http.HttpServletRequest; +import net.gepafin.tendermanagement.config.Translator; +import net.gepafin.tendermanagement.constants.GepafinConstant; +import net.gepafin.tendermanagement.enums.UserActionContextEnum; +import net.gepafin.tendermanagement.enums.UserActionLogsEnum; +import net.gepafin.tendermanagement.model.request.UserActionRequest; +import net.gepafin.tendermanagement.model.response.ApplicationAmendmentRequestResponse; +import net.gepafin.tendermanagement.model.response.PecEmailLogResponse; +import net.gepafin.tendermanagement.model.response.PecMailResponse; +import net.gepafin.tendermanagement.model.util.Response; +import net.gepafin.tendermanagement.service.PecMailService; +import net.gepafin.tendermanagement.util.LoggingUtil; +import net.gepafin.tendermanagement.web.rest.api.PecMailApi; +import net.gepafin.tendermanagement.web.rest.api.errors.Status; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +@RestController +@RequestMapping("${openapi.gepafin.base-path:/v1/pecMail}") +public class PecMailController implements PecMailApi { + + @Autowired + private LoggingUtil loggingUtil; + + @Autowired + private PecMailService pecMailService; + + @Override + public ResponseEntity> sendPecMail(HttpServletRequest request,List userActionIds) { + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.EMAIL) + .actionContext(UserActionContextEnum.SEND_PEC_MAIL).build()); + +// PecMailResponse pecMailResponse=pecMailService.sendPecMail(request,userActionId); + + return ResponseEntity.status(HttpStatus.OK) + .body(new Response<>(null, Status.SUCCESS, Translator.toLocale(GepafinConstant.MAIL_SENT_SUCCESSFULLY))); + + } + + @Override + public ResponseEntity>> getEmailLogByUserActionId(HttpServletRequest request, Long userActionId) { + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.EMAIL) + .actionContext(UserActionContextEnum.FETCH_EMAIL_LOG).build()); + + List pecEmailLogResponse=pecMailService.getEmailLogByUserActionId(request,userActionId); + + return ResponseEntity.status(HttpStatus.OK) + .body(new Response<>(pecEmailLogResponse, Status.SUCCESS, Translator.toLocale(GepafinConstant.EMAIL_LOG_FETCHED))); + + } + + @Override + public ResponseEntity>> getAllEmailLogs(HttpServletRequest request) { + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.EMAIL) + .actionContext(UserActionContextEnum.FETCH_ALL_EMAIL_LOG).build()); + + List pecMailResponses=pecMailService.getAllEmailLogs(request); + + return ResponseEntity.status(HttpStatus.OK) + .body(new Response<>(pecMailResponses, Status.SUCCESS, Translator.toLocale(GepafinConstant.EMAIL_LOG_FETCHED))); + } +} 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 e96d0bf7..178e4ad4 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 @@ -3135,4 +3135,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/message_en.properties b/src/main/resources/message_en.properties index 48b7a1d6..a2aeca61 100644 --- a/src/main/resources/message_en.properties +++ b/src/main/resources/message_en.properties @@ -424,3 +424,4 @@ files.required.for.contract=Files are required for contract. application.contract.already.exist=Application contract already exist for this application. application.not.approved=Application is not approved. subject.body.required=Subject and body is required to create contract. +mail.send.successfully=Mail sent succesfully. diff --git a/src/main/resources/message_it.properties b/src/main/resources/message_it.properties index 9a0f2724..8507f202 100644 --- a/src/main/resources/message_it.properties +++ b/src/main/resources/message_it.properties @@ -415,3 +415,4 @@ files.required.for.contract=I file sono necessari per il contratto. application.contract.already.exist=Il contratto di applicazione esiste gi per questa applicazione. application.not.approved=La domanda non stata approvata. subject.body.required=Per creare un contratto sono necessari oggetto e corpo. +mail.send.successfully=Email inviata con successo. From 3f28d83f5bb8f1fa3d678ca227fc827a3233a77a Mon Sep 17 00:00:00 2001 From: rajesh Date: Mon, 10 Nov 2025 14:22:08 +0530 Subject: [PATCH 69/75] Updated credentials --- src/main/resources/application.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index f2db0c1e..7fffc70b 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -27,8 +27,8 @@ springdoc.swagger-ui.tagsSorter=alpha call.id=10 #aws configuration -aws.access.key.id=AKIAVWDQWCUENKE7QGXP -aws.secret.access.key=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 +aws.access.key.id=AKIAVWDQWCUEFJP3T6OP +aws.secret.access.key=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 aws.s3.region=eu-west-1 aws.s3.bucket.name=mementoresources aws.s3.url = https://mementoresources.s3.eu-west-1.amazonaws.com/ From f6d2583b77ce95e5267ef7fbda52a3e0f296e32c Mon Sep 17 00:00:00 2001 From: rajesh Date: Mon, 10 Nov 2025 17:21:01 +0530 Subject: [PATCH 70/75] Updated code --- .../tendermanagement/repositories/EmailLogRepository.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/EmailLogRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/EmailLogRepository.java index 0d6a2202..3a021127 100644 --- a/src/main/java/net/gepafin/tendermanagement/repositories/EmailLogRepository.java +++ b/src/main/java/net/gepafin/tendermanagement/repositories/EmailLogRepository.java @@ -25,7 +25,7 @@ public interface EmailLogRepository extends JpaRepository { ); @Query(value = """ - SELECT DISTINCT ON (user_action_id) * FROM email_log WHERE send_status = 'PENDING' AND is_deleted = false AND email_service_type = 'PEC_SERVICE' """, nativeQuery = true) + SELECT DISTINCT ON (user_action_id) * FROM gepafin_schema.email_log WHERE send_status = 'PENDING' AND is_deleted = false """, nativeQuery = true) List findPendingPECEmailLogs(); From 05c3c95b6508b32bb39a602fc099d8db218c7d4a Mon Sep 17 00:00:00 2001 From: rajesh Date: Tue, 11 Nov 2025 15:23:40 +0530 Subject: [PATCH 71/75] Done ticket GEPAFINBE-6141 --- .../dao/ApplicationAmendmentRequestDao.java | 5 +- .../tendermanagement/dao/ApplicationDao.java | 36 +++-- .../tendermanagement/dao/EmailDao.java | 5 +- .../tendermanagement/dao/EmailLogDao.java | 12 +- .../dao/EmailNotificationDao.java | 103 ++++++------ .../tendermanagement/dao/PecMailDao.java | 16 +- .../gepafin/tendermanagement/dao/UserDao.java | 32 ++-- .../entities/EmailLogEntity.java | 3 + .../repositories/EmailLogRepository.java | 5 +- .../service/PecMailService.java | 2 +- .../service/impl/EmailService.java | 3 +- .../service/impl/MailgunEmailService.java | 31 ++-- .../service/impl/PecEmailService.java | 150 ++++++++++++------ .../service/impl/PecMailSerivceImpl.java | 2 +- .../service/impl/SystemEmailService.java | 57 ++++--- .../web/rest/api/DashboardApi.java | 2 +- .../web/rest/api/PecMailApi.java | 2 +- .../web/rest/api/impl/PecMailController.java | 6 +- .../db/changelog/db.changelog-1.0.0.xml | 6 + 19 files changed, 291 insertions(+), 187 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java index 73dc49ad..66cb3ed7 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java @@ -1295,8 +1295,9 @@ public class ApplicationAmendmentRequestDao { if (Boolean.TRUE.equals(amendment.getIsEmail()) && email != null && !email.isEmpty()) { log.info("Sending reminder email to: {}", email); EmailLogRequest emailLogRequest = emailLogDao.createEmailLogRequest(emailTemplate.getEmailScenario(), RecipientTypeEnum.USER, beneficiaryUser.getId(), email, - beneficiaryUser.getId(), applicationEntity.getId(), amendment.getId(), applicationEntity.getCall().getId()); - emailNotificationDao.sendMail(hub.getId(), subject, body, List.of(email), emailLogRequest); + beneficiaryUser.getId(), applicationEntity.getId(), amendment.getId(), applicationEntity.getCall().getId(),subject,body); + EmailLogEntity emailLog=emailLogDao.createEmailLog(emailLogRequest,null); + emailNotificationDao.sendMail(hub.getId(), subject, body, List.of(email), emailLog); EmailSendResponse emailSendResponse = emailDao.buildEmailSendResponseFromRequest(request); List responses = List.of(emailSendResponse); if (!Boolean.TRUE.equals(emailSendResponse.getIsEmailSend())){ diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java index 56e267be..bfc0e4d5 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java @@ -1232,7 +1232,7 @@ public class ApplicationDao { // Replace placeholders in the subject and body String subject = Utils.replacePlaceholders(systemEmailTemplateResponse.getSubject(), subjectPlaceholders); String body = Utils.replacePlaceholders(systemEmailTemplateResponse.getHtmlContent(), bodyPlaceholders); - EmailLogRequest emailLogRequest=emailLogDao.createEmailLogRequest(systemEmailTemplateResponse.getEmailScenario(),RecipientTypeEnum.USER,userEntity.getId(),userEntity.getEmail(),userEntity.getId(),applicationEntity.getId(),null,applicationEntity.getCall().getId()); + EmailLogRequest emailLogRequest=emailLogDao.createEmailLogRequest(systemEmailTemplateResponse.getEmailScenario(),RecipientTypeEnum.USER,userEntity.getId(),userEntity.getEmail(),userEntity.getId(),applicationEntity.getId(),null,applicationEntity.getCall().getId(),subject,body); String email = userEntity.getEmail(); if (userEntity.getBeneficiary() != null) { emailLogRequest.setRecipientType(RecipientTypeEnum.BENEFICIARY); @@ -1245,12 +1245,14 @@ public class ApplicationDao { } emailLogRequest.setRecipientId(userEntity.getBeneficiary().getId()); } - emailNotificationDao.sendMail(hub.getId(), subject, body, List.of(email),emailLogRequest); + EmailLogEntity emailLogEntity=emailLogDao.createEmailLog(emailLogRequest,null); + emailNotificationDao.sendMail(hub.getId(), subject, body, List.of(email),emailLogEntity); if (Boolean.TRUE.equals(hub.getUniqueUuid().equals(defaultHubUuid)) && userEntity.getBeneficiary() != null) { emailLogRequest.setRecipientType(RecipientTypeEnum.BENEFICIARY); email = userEntity.getBeneficiary().getEmail(); emailLogRequest.setRecipientId(userEntity.getBeneficiary().getId()); - emailNotificationDao.sendMail(hub.getId(), subject, body, List.of(email),emailLogRequest); + EmailLogEntity emailLog=emailLogDao.createEmailLog(emailLogRequest,null); + emailNotificationDao.sendMail(hub.getId(), subject, body, List.of(email),emailLog); } List recipientEmails = new ArrayList<>(); // recipientEmails.add(email); @@ -1277,7 +1279,8 @@ public class ApplicationDao { emailLogRequest.setRecipientType(RecipientTypeEnum.COMPANY); emailLogRequest.setRecipientEmails(String.valueOf(recipientEmails)); } - emailNotificationDao.sendMail(hub.getId(), subject, body, recipientEmails,emailLogRequest); + EmailLogEntity emailLog=emailLogDao.createEmailLog(emailLogRequest,null); + emailNotificationDao.sendMail(hub.getId(), subject, body, recipientEmails,emailLog); } private void sendMailTodefaultSystemAndGepafin(UserEntity userEntity, ApplicationEntity applicationEntity) { CallEntity call = applicationEntity.getCall(); @@ -1319,7 +1322,7 @@ public class ApplicationDao { String subject = Utils.replacePlaceholders(systemEmailTemplateResponse.getSubject(), subjectPlaceholders); String body = Utils.replacePlaceholders(systemEmailTemplateResponse.getHtmlContent(), bodyPlaceholders); - EmailLogRequest emailLogRequest=emailLogDao.createEmailLogRequest(systemEmailTemplateResponse.getEmailScenario(),RecipientTypeEnum.PROPERTIES,null,userEntity.getEmail(),userEntity.getId(),applicationEntity.getId(),null,applicationEntity.getCall().getId()); + EmailLogRequest emailLogRequest=emailLogDao.createEmailLogRequest(systemEmailTemplateResponse.getEmailScenario(),RecipientTypeEnum.PROPERTIES,null,userEntity.getEmail(),userEntity.getId(),applicationEntity.getId(),null,applicationEntity.getCall().getId(),subject,body); List hubEmails = Arrays.stream(hub.getEmail().split(",")) .map(String::trim) @@ -1327,9 +1330,11 @@ public class ApplicationDao { .toList(); emailLogRequest.setRecipientEmails(hub.getEmail()); - emailNotificationDao.sendMail(hub.getId(), subject, body,hubEmails,emailLogRequest); + EmailLogEntity emailLogEntity=emailLogDao.createEmailLog(emailLogRequest,null); + emailNotificationDao.sendMail(hub.getId(), subject, body,hubEmails,emailLogEntity); emailLogRequest.setRecipientEmails(rinaldoEmail); - emailNotificationDao.sendMail(hub.getId(), subject, body, List.of(rinaldoEmail),emailLogRequest); + EmailLogEntity emailLog=emailLogDao.createEmailLog(emailLogRequest,null); + emailNotificationDao.sendMail(hub.getId(), subject, body, List.of(rinaldoEmail),emailLog); } public ApplicationSignedDocumentResponse uploadSignedDocument(HttpServletRequest request, Long applicationId, MultipartFile file) { @@ -2447,14 +2452,14 @@ public class ApplicationDao { } - public void sendApplicationSubmissionFailureEmail(EmailLogRequest emailLogRequest){ + public void sendApplicationSubmissionFailureEmail(EmailLogEntity emailLogEntity){ - Long callId = emailLogRequest.getCallId(); + Long callId = emailLogEntity.getCallId(); CallEntity call = callService.validateCall(callId); HubEntity hub = call.getHub(); - Long userId = emailLogRequest.getUserId(); + Long userId = emailLogEntity.getUserId(); UserEntity user = userService.validateUser(userId); - Long applicationId = emailLogRequest.getApplicatioId(); + Long applicationId = emailLogEntity.getApplicationId(); ApplicationEntity applicationEntity = validateApplication(applicationId); CompanyEntity company = companyService.validateCompany(applicationEntity.getCompanyId()); @@ -2467,7 +2472,7 @@ public class ApplicationDao { subjectPlaceholders.put("{{call_name}}", call.getName()); Map bodyPlaceholders = new HashMap<>(); - bodyPlaceholders.put("{{scenario}}",emailLogRequest.getEmailType().getValue()); + bodyPlaceholders.put("{{scenario}}",emailLogEntity.getEmailType()); bodyPlaceholders.put("{{call_name}}", call.getName()); bodyPlaceholders.put("{{application_id}}", applicationEntity.getId().toString()); bodyPlaceholders.put("{{company_name}}", company.getCompanyName()); @@ -2476,15 +2481,16 @@ public class ApplicationDao { protocolNumber= String.valueOf(applicationEntity.getProtocol().getProtocolNumber()); } bodyPlaceholders.put("{{protocol_number}}", protocolNumber); - bodyPlaceholders.put("{{user_action_id}}",emailLogRequest.getUserActionId().toString()); + bodyPlaceholders.put("{{user_action_id}}",emailLogEntity.getUserAction().getId().toString()); String subject = Utils.replacePlaceholders(systemEmailTemplateResponse.getSubject(), subjectPlaceholders); String body = Utils.replacePlaceholders(systemEmailTemplateResponse.getHtmlContent(), bodyPlaceholders); - emailLogRequest=emailLogDao.createEmailLogRequest(systemEmailTemplateResponse.getEmailScenario(),RecipientTypeEnum.PROPERTIES,null,user.getEmail(),user.getId(),applicationEntity.getId(),null,callId); + EmailLogRequest emailLogRequest=emailLogDao.createEmailLogRequest(systemEmailTemplateResponse.getEmailScenario(),RecipientTypeEnum.PROPERTIES,null,user.getEmail(),user.getId(),applicationEntity.getId(),null,callId,subject,body); emailLogRequest.setRecipientEmails(GepafinConstant.RINALDO_EMAIL); - emailNotificationDao.sendMail(hub.getId(), subject, body, List.of(GepafinConstant.RINALDO_EMAIL),emailLogRequest); + EmailLogEntity newEmailLogEntity=emailLogDao.createEmailLog(emailLogRequest,null); + emailNotificationDao.sendMail(hub.getId(), subject, body, List.of(GepafinConstant.RINALDO_EMAIL),newEmailLogEntity); } public byte[] downloadRankingCsv(Long callId,UserEntity userEntity) { diff --git a/src/main/java/net/gepafin/tendermanagement/dao/EmailDao.java b/src/main/java/net/gepafin/tendermanagement/dao/EmailDao.java index 244df6a4..ac790906 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/EmailDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/EmailDao.java @@ -73,8 +73,9 @@ public class EmailDao { log.getUserId(), log.getApplicationId(), log.getAmendmentId(), - log.getCallId() + log.getCallId(),log.getEmailSubject(),log.getEmailBody() ); + EmailLogEntity emailLogEntity=emailLogDao.createEmailLog(emailLogRequest,Utils.convertJsonStringToList(log.getAttachments(),String.class)); List recipients = Utils.commaSeparatedStringToList(log.getRecipientEmails()); CallEntity call = callService.validateCall(log.getCallId()); @@ -83,7 +84,7 @@ public class EmailDao { log.getEmailSubject(), log.getEmailBody(), recipients, - emailLogRequest + emailLogEntity ); } EmailSendResponse emailSendResponse = buildEmailSendResponseFromRequest(request); diff --git a/src/main/java/net/gepafin/tendermanagement/dao/EmailLogDao.java b/src/main/java/net/gepafin/tendermanagement/dao/EmailLogDao.java index 747c9e83..9bc89426 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/EmailLogDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/EmailLogDao.java @@ -10,10 +10,12 @@ import net.gepafin.tendermanagement.repositories.EmailLogRepository; import net.gepafin.tendermanagement.repositories.UserActionsRepository; import net.gepafin.tendermanagement.util.DateTimeUtil; import net.gepafin.tendermanagement.util.LoggingUtil; +import net.gepafin.tendermanagement.util.Utils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.time.LocalDateTime; +import java.util.List; @Component public class EmailLogDao { @@ -28,7 +30,7 @@ public class EmailLogDao { private LoggingUtil loggingUtil; - public EmailLogEntity createEmailLog(EmailLogRequest emailLogRequest) { + public EmailLogEntity createEmailLog(EmailLogRequest emailLogRequest,List attachments) { EmailLogEntity emailLogEntity = new EmailLogEntity(); emailLogEntity.setEmailType(emailLogRequest.getEmailType().getValue()); @@ -37,17 +39,17 @@ public class EmailLogDao { emailLogEntity.setEmailSubject(emailLogRequest.getEmailSubject()); emailLogEntity.setEmailBody(emailLogRequest.getEmailBody()); emailLogEntity.setSendStatus(emailLogRequest.getSendStatus()); - emailLogEntity.setSendDateTime(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); // Set to now if null emailLogEntity.setErrorMessage(emailLogRequest.getErrorMessage()); emailLogEntity.setUserId(emailLogRequest.getUserId()); emailLogEntity.setEmailServiceResponse(emailLogRequest.getEmailServiceResponse()); emailLogEntity.setRecipientEmails(emailLogRequest.getRecipientEmails()); - emailLogEntity.setEmailServiceType(emailLogRequest.getEmailServiceType().getValue()); emailLogEntity.setIsDeleted(false); emailLogEntity.setApplicationId(emailLogRequest.getApplicatioId()); emailLogEntity.setAmendmentId(emailLogRequest.getAmendmentId()); emailLogEntity.setCallId(emailLogRequest.getCallId()); emailLogEntity.setUserAction(loggingUtil.getUserActionLogById(emailLogRequest.getUserActionId())); + emailLogEntity.setSendStatus(StatusTypeEnum.PENDING.getValue()); + emailLogEntity.setAttachments(Utils.convertListToJsonString(attachments)); emailLogEntity = saveEmailLogEntity(emailLogEntity); return emailLogEntity; } @@ -55,7 +57,7 @@ public class EmailLogDao { return emailLogRepository.save(emailLogEntity); } public EmailLogRequest createEmailLogRequest(EmailScenarioTypeEnum emailType, RecipientTypeEnum recipientType, Long recipientId, - String recipientEmails, Long userId,Long applicationId,Long amendmentId,Long callId) { + String recipientEmails, Long userId, Long applicationId, Long amendmentId, Long callId, String subject, String body) { EmailLogRequest emailLogRequest = new EmailLogRequest(); Long userActionId =(Long) request.getAttribute(GepafinConstant.USER_ACTION_ID); emailLogRequest.setEmailType(emailType); @@ -67,6 +69,8 @@ public class EmailLogDao { emailLogRequest.setAmendmentId(amendmentId); emailLogRequest.setCallId(callId); emailLogRequest.setUserActionId(userActionId); + emailLogRequest.setEmailSubject(subject); + emailLogRequest.setEmailBody(body); return emailLogRequest; } } diff --git a/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java index da689b79..8bf116aa 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java @@ -143,23 +143,9 @@ public class EmailNotificationDao { applicationAmendmentRequest = applicationAmendmentRequestDao.validateApplicationAmendmentRequest(amendmentId); } List attachmentRequests =new ArrayList<>(); - S3DocxProcessor processor = new S3DocxProcessor(s3Client); List urls=new ArrayList<>(); - Map replacements=new HashMap<>(); List documentEntities=new ArrayList<>(); if(systemEmailTemplateResponse.getEmailScenario().equals(EmailScenarioTypeEnum.SPECIAL_APPLICATION_AMENDMENT_REQUESTED)) { - String amount=Utils.convertToItalianFormat(String.valueOf(applicationEntity.getAmountAccepted())); - String protocolNumber=applicationEntity.getProtocol().getExternalProtocolNumber(); - if(protocolNumber==null){ - protocolNumber= String.valueOf(applicationEntity.getProtocol().getProtocolNumber()); - } - replacements = Map.of( - "{call_name}", applicationEntity.getCall().getName(), - "{amount_accepted}", amount, - "{pec}", "bandi.gepafin@legalmail.it", - "{company_name}", company.getCompanyName(), - "{protocol_number}", protocolNumber - ); if(Boolean.TRUE.equals(AmendmentDocumentTypeEnum.ALTRE_GARANZIE.getValue().equals(applicationAmendmentRequest.getAmendmentDocumentType()))){ documentEntities=documentRepository.findBySourceInAndIsDeletedFalse(List.of(applicationAmendmentRequest.getAmendmentDocumentType(),"MODELLO_AUTOCERTIFICAZIONE","MODELLO_PRIVACY")); }else { @@ -192,20 +178,7 @@ public class EmailNotificationDao { urls = documentEntities.stream() .map(DocumentEntity::getFilePath) // or getUrl() .collect(Collectors.toList()); - if(Boolean.FALSE.equals(urls.isEmpty())) { - 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(); String contactEmail = userWithCompany.getContactEmail(); @@ -217,22 +190,25 @@ public class EmailNotificationDao { recipientEmails.add(userWithCompany.getPec()); } EmailLogRequest emailLogRequest = emailLogDao.createEmailLogRequest(systemEmailTemplateResponse.getEmailScenario(), RecipientTypeEnum.COMPANY,company.getId() , - String.valueOf(recipientEmails), userEntity.getId(), applicationEntity.getId(), amendmentId, applicationEntity.getCall().getId()); + String.valueOf(recipientEmails), userEntity.getId(), applicationEntity.getId(), amendmentId, applicationEntity.getCall().getId(),subject,body); emailLogRequest.setAttachments(attachmentRequests); - sendMail(applicationEntity.getHubId(), subject, body, recipientEmails, emailLogRequest); + EmailLogEntity emailLogEntity=emailLogDao.createEmailLog(emailLogRequest,urls); + sendMail(applicationEntity.getHubId(), subject, body, recipientEmails, emailLogEntity); } 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()); + companyEmail, userEntity.getId(), applicationEntity.getId(), amendmentId, applicationEntity.getCall().getId(),subject,body); emailLogRequest.setAttachments(attachmentRequests); - sendMail(applicationEntity.getHubId(), subject, body, List.of(companyEmail), emailLogRequest); + EmailLogEntity emailLogEntity=emailLogDao.createEmailLog(emailLogRequest,urls); + sendMail(applicationEntity.getHubId(), subject, body, List.of(companyEmail), emailLogEntity); } 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()); + contactEmail, userEntity.getId(), applicationEntity.getId(), amendmentId, applicationEntity.getCall().getId(),subject,body); emailLogRequest.setAttachments(attachmentRequests); - sendMail(applicationEntity.getHubId(), subject, body, List.of(contactEmail), emailLogRequest); + EmailLogEntity emailLogEntity=emailLogDao.createEmailLog(emailLogRequest,urls); + sendMail(applicationEntity.getHubId(), subject, body, List.of(contactEmail), emailLogEntity); } } @@ -246,16 +222,18 @@ public class EmailNotificationDao { beneficiaryEmail=userEntity.getBeneficiary().getEmail(); } EmailLogRequest emailLogRequest = emailLogDao.createEmailLogRequest(systemEmailTemplateResponse.getEmailScenario(), recipientTypeEnum,userEntity.getBeneficiary().getId() , - beneficiaryEmail, userEntity.getId(), applicationEntity.getId(), amendmentId, applicationEntity.getCall().getId()); + beneficiaryEmail, userEntity.getId(), applicationEntity.getId(), amendmentId, applicationEntity.getCall().getId(),subject,body); emailLogRequest.setAttachments(attachmentRequests); - sendMail(applicationEntity.getHubId(), subject, body, List.of(beneficiaryEmail), emailLogRequest); + EmailLogEntity emailLogEntity=emailLogDao.createEmailLog(emailLogRequest,urls); + sendMail(applicationEntity.getHubId(), subject, body, List.of(beneficiaryEmail), emailLogEntity); } if (Boolean.TRUE.equals(userEntity.getHub().getUniqueUuid().equals(defaultHubUuid)) && userEntity.getBeneficiary() != null) { String beneficiaryEmail = userEntity.getBeneficiary().getEmail(); EmailLogRequest emailLogRequest = emailLogDao.createEmailLogRequest(systemEmailTemplateResponse.getEmailScenario(), RecipientTypeEnum.BENEFICIARY, userEntity.getBeneficiary().getId(), - beneficiaryEmail, userEntity.getId(), applicationEntity.getId(), amendmentId, applicationEntity.getCall().getId()); + beneficiaryEmail, userEntity.getId(), applicationEntity.getId(), amendmentId, applicationEntity.getCall().getId(),subject,body); emailLogRequest.setAttachments(attachmentRequests); - sendMail(applicationEntity.getHubId(), subject, body, List.of(beneficiaryEmail), emailLogRequest); + EmailLogEntity emailLogEntity=emailLogDao.createEmailLog(emailLogRequest,urls); + sendMail(applicationEntity.getHubId(), subject, body, List.of(beneficiaryEmail), emailLogEntity); } if(userEntity.getHub().getEmail() != null){ String hubEmails = userEntity.getHub().getEmail(); @@ -264,19 +242,21 @@ public class EmailNotificationDao { hubEmail = hubEmail.trim(); if (!hubEmail.isEmpty()) { EmailLogRequest emailLogRequest = emailLogDao.createEmailLogRequest(systemEmailTemplateResponse.getEmailScenario(), RecipientTypeEnum.PROPERTIES,null, - hubEmail, userEntity.getId(), applicationEntity.getId(), amendmentId, applicationEntity.getCall().getId()); + hubEmail, userEntity.getId(), applicationEntity.getId(), amendmentId, applicationEntity.getCall().getId(),subject,body); emailLogRequest.setAttachments(attachmentRequests); - sendMail(applicationEntity.getHubId(), subject, body, List.of(hubEmail), emailLogRequest); + EmailLogEntity emailLogEntity=emailLogDao.createEmailLog(emailLogRequest,urls); + sendMail(applicationEntity.getHubId(), subject, body, List.of(hubEmail), emailLogEntity); } } } if (GepafinConstant.RINALDO_EMAIL.equals(rinaldoEmail)) { EmailLogRequest emailLogRequest = emailLogDao.createEmailLogRequest(systemEmailTemplateResponse.getEmailScenario(), RecipientTypeEnum.PROPERTIES,null , - rinaldoEmail, userEntity.getId(), applicationEntity.getId(), amendmentId, applicationEntity.getCall().getId()); + rinaldoEmail, userEntity.getId(), applicationEntity.getId(), amendmentId, applicationEntity.getCall().getId(),subject,body); //SMTP emailLogRequest.setAttachments(attachmentRequests); - sendMail(null, subject, body, List.of(rinaldoEmail), emailLogRequest); + EmailLogEntity emailLogEntity=emailLogDao.createEmailLog(emailLogRequest,urls); + sendMail(null, subject, body, List.of(rinaldoEmail), emailLogEntity); } if (applicationEvaluationEntity.isPresent()) { Long preInstructorId = applicationEvaluationEntity.get().getUserId(); // Assuming UserEntity has an email field @@ -284,9 +264,10 @@ public class EmailNotificationDao { String preInstructorEmail = instructorUser.getEmail(); if (preInstructorEmail != null && !preInstructorEmail.isEmpty()) { EmailLogRequest emailLogRequest = emailLogDao.createEmailLogRequest(systemEmailTemplateResponse.getEmailScenario(), RecipientTypeEnum.INSTRUCTOR, instructorUser.getId(), - preInstructorEmail, userEntity.getId(), applicationEntity.getId(), amendmentId, applicationEntity.getCall().getId()); + preInstructorEmail, userEntity.getId(), applicationEntity.getId(), amendmentId, applicationEntity.getCall().getId(),subject,body); emailLogRequest.setAttachments(attachmentRequests); - sendMail(applicationEntity.getHubId(), subject, body, List.of(preInstructorEmail), emailLogRequest); + EmailLogEntity emailLogEntity=emailLogDao.createEmailLog(emailLogRequest,urls); + sendMail(applicationEntity.getHubId(), subject, body, List.of(preInstructorEmail), emailLogEntity); } } } @@ -435,18 +416,31 @@ public class EmailNotificationDao { sendEmail(applicationEntity, SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum.INADMISSIBILITY_TEMPLATE, bodyPlaceholders, null,null,emailType); } - public void sendMail(Long hubId, String subject, String body, List recipientEmails, EmailLogRequest emailLogRequest) { + public void sendMail(Long hubId, String subject, String body, List recipientEmails, EmailLogEntity emailLogEntity) { EmailConfig emailConfig = new EmailConfig(); + Boolean isSendEmail=Boolean.TRUE; + + HubEntity hubEntity = hubRepository.findById(hubId).orElseThrow(() -> new IllegalArgumentException("Invalid Hub ID: " + hubId)); + if(Boolean.TRUE.equals(hubEntity.getUniqueUuid().equals(defaultHubUuid))){ + if(Boolean.FALSE.equals(emailLogEntity.getEmailType().equals(EmailScenarioTypeEnum.USER_CREATION.getValue())) + || Boolean.FALSE.equals(emailLogEntity.getEmailType().equals(EmailScenarioTypeEnum.APPLICATION_AMENDMENT_REMINDER.getValue())) + || Boolean.FALSE.equals(emailLogEntity.getEmailType().equals(EmailScenarioTypeEnum.APPLICATION_SUBMITTED.getValue())) + || Boolean.FALSE.equals(emailLogEntity.getEmailType().equals(EmailScenarioTypeEnum.PASSWORD_RESET_REQUEST.getValue()))) { + isSendEmail = Boolean.FALSE; + } + } if (recipientEmails.stream().anyMatch(email -> email.equals(GepafinConstant.RINALDO_EMAIL))) { + emailConfig.setEmailServiceType(EmailServiceTypeEnum.SYSTEM_EMAIL_SERVICE.getValue()); EmailService emailService = emailServiceFactory.getEmailService(emailConfig.getEmailServiceType()); - emailService.sendEmail(subject, body, recipientEmails, emailConfig, emailLogRequest); + emailService.sendEmail(subject, body, recipientEmails, emailConfig,emailLogEntity,isSendEmail); } else { emailConfig = retrieveEmailConfig(hubId); EmailService emailService = emailServiceFactory.getEmailService(emailConfig.getEmailServiceType()); - emailService.sendEmail(subject, body, recipientEmails, emailConfig, emailLogRequest); + emailService.sendEmail(subject, body, recipientEmails, emailConfig,emailLogEntity,isSendEmail); } + } public EmailConfig retrieveEmailConfig(Long hubId) { @@ -554,4 +548,19 @@ public class EmailNotificationDao { EmailContentResponse emailContentResponse= new EmailContentResponse(subject, body, systemEmailTemplateResponse); sendEmails(applicationEntity, user, null,null,emailContentResponse.getSystemEmailTemplateResponse(),emailContentResponse.getSubject(),emailContentResponse.getBody(),applicationContractEntity.getId()); } + public void sendPendingMail(Long hubId, String subject, String body, List recipientEmails, EmailLogEntity emailLogEntity) { + + EmailConfig emailConfig = new EmailConfig(); + if (recipientEmails.stream().anyMatch(email -> email.equals(GepafinConstant.RINALDO_EMAIL))) { + + emailConfig.setEmailServiceType(EmailServiceTypeEnum.SYSTEM_EMAIL_SERVICE.getValue()); + EmailService emailService = emailServiceFactory.getEmailService(emailConfig.getEmailServiceType()); + emailService.sendEmail(subject, body, recipientEmails, emailConfig,emailLogEntity,true); + } else { + emailConfig = retrieveEmailConfig(hubId); + EmailService emailService = emailServiceFactory.getEmailService(emailConfig.getEmailServiceType()); + emailService.sendEmail(subject, body, recipientEmails, emailConfig,emailLogEntity,true); + } + + } } \ No newline at end of file diff --git a/src/main/java/net/gepafin/tendermanagement/dao/PecMailDao.java b/src/main/java/net/gepafin/tendermanagement/dao/PecMailDao.java index f24c6be8..18240044 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/PecMailDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/PecMailDao.java @@ -50,24 +50,28 @@ public class PecMailDao { private ApplicationService applicationService; - public PecMailResponse sendPecMail(HttpServletRequest request, List userActionIds) { + public List sendPecMail(HttpServletRequest request, List userActionIds) { + List pecMailResponses=new ArrayList<>(); for (Long userActionId: userActionIds) { List emailLogs = getEmailLogEntities(request, userActionId); for (EmailLogEntity log : emailLogs) { List recipients = Utils.commaSeparatedStringToList(log.getRecipientEmails()); CallEntity call = callService.validateCall(log.getCallId()); - emailNotificationDao.sendMail( + emailNotificationDao.sendPendingMail( call.getHub().getId(), log.getEmailSubject(), log.getEmailBody(), recipients, - null + log ); - + ApplicationEntity applicationEntity=applicationService.validateApplication(log.getApplicationId()); + String callName=applicationEntity.getCall().getName(); + PecMailResponse pecMailResponse=createPecMailResponse(log.getUserAction().getId(),log,callName); + pecMailResponses.add(pecMailResponse); } } - return null; + return pecMailResponses; } private List getEmailLogEntities(HttpServletRequest request, Long userActionId) { @@ -77,7 +81,7 @@ public class PecMailDao { } validator.validateHubId(request, userActionEntity.getHubId()); - List emailLogs = emailLogRepository.findByUserActionIdAndEmailServiceTypeAndSendStatus(userActionId, EmailServiceTypeEnum.PEC_SERVICE.getValue(), StatusTypeEnum.PENDING.getValue()); + List emailLogs = emailLogRepository.findByUserActionIdAndSendStatusAndIsDeletedFalse(userActionId,StatusTypeEnum.PENDING.getValue()); if (emailLogs.isEmpty()) { log.info("No emails found for given userActionId: {}", userActionId); diff --git a/src/main/java/net/gepafin/tendermanagement/dao/UserDao.java b/src/main/java/net/gepafin/tendermanagement/dao/UserDao.java index 0403fde3..ab8f8831 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/UserDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/UserDao.java @@ -192,19 +192,19 @@ public class UserDao { : SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum.USER_ONBOARDING_BANDI; emailTemplate = systemEmailTemplatesService.retrieveTemplateByTypeAndCall(templateType, userEntity.getHub(), null); - + Map placeholders = replacePlaceholders(userEntity, userReq); + String body = Utils.replacePlaceholders(emailTemplate.getHtmlContent(), placeholders); EmailLogRequest emailLogRequest = emailLogDao.createEmailLogRequest(emailTemplate.getEmailScenario(), RecipientTypeEnum.USER, userEntity.getId(), userEntity.getEmail(), - userEntity.getId(), null, null, null); + userEntity.getId(), null, null, null,emailTemplate.getSubject(),body); - Map placeholders = replacePlaceholders(userEntity, userReq); - String body = Utils.replacePlaceholders(emailTemplate.getHtmlContent(), placeholders); + EmailLogEntity emailLogEntity=emailLogDao.createEmailLog(emailLogRequest,null); emailNotificationDao.sendMail( userEntity.getHub().getId(), emailTemplate.getSubject(), body, List.of(userEntity.getEmail()), - emailLogRequest + emailLogEntity ); } @@ -545,15 +545,7 @@ public class UserDao { redirectUrl = user.getHub().getDomainName(); } - EmailLogRequest emailLogRequest = emailLogDao.createEmailLogRequest( - emailTemplate.getEmailScenario(), - RecipientTypeEnum.USER, - user.getId(), - user.getEmail(), - user.getId(), - null, - null, - null); + redirectUrl = String.format( user.getHub().getDomainName() + GepafinConstant.RESET_PASSWORD_URL_FORMAT, token, @@ -569,12 +561,22 @@ public class UserDao { "{{user_name}}", userName, "{{reset_password_link}}", redirectUrl )); + EmailLogRequest emailLogRequest = emailLogDao.createEmailLogRequest( + emailTemplate.getEmailScenario(), + RecipientTypeEnum.USER, + user.getId(), + user.getEmail(), + user.getId(), + null, + null, + null,subject,body); + EmailLogEntity emailLogEntity=emailLogDao.createEmailLog(emailLogRequest,null); emailNotificationDao.sendMail( user.getHub().getId(), subject, body, List.of(user.getEmail()), - emailLogRequest + emailLogEntity ); log.info("Password reset token email sent to: {}", user.getEmail()); diff --git a/src/main/java/net/gepafin/tendermanagement/entities/EmailLogEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/EmailLogEntity.java index 1f8f3fe5..0a4dfc90 100644 --- a/src/main/java/net/gepafin/tendermanagement/entities/EmailLogEntity.java +++ b/src/main/java/net/gepafin/tendermanagement/entities/EmailLogEntity.java @@ -59,5 +59,8 @@ public class EmailLogEntity extends BaseEntity{ @ManyToOne @JoinColumn(name = "user_action_id") private UserActionEntity userAction; + + @Column(name = "ATTACHMENTS") + private String attachments; } diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/EmailLogRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/EmailLogRepository.java index 0d6a2202..057afff7 100644 --- a/src/main/java/net/gepafin/tendermanagement/repositories/EmailLogRepository.java +++ b/src/main/java/net/gepafin/tendermanagement/repositories/EmailLogRepository.java @@ -24,8 +24,11 @@ public interface EmailLogRepository extends JpaRepository { String sendStatus ); + List findByUserActionIdAndSendStatusAndIsDeletedFalse(Long userActionId,String status); + + @Query(value = """ - SELECT DISTINCT ON (user_action_id) * FROM email_log WHERE send_status = 'PENDING' AND is_deleted = false AND email_service_type = 'PEC_SERVICE' """, nativeQuery = true) + SELECT DISTINCT ON (user_action_id) * FROM gepafin_schema.email_log WHERE send_status = 'PENDING' AND is_deleted = false""", nativeQuery = true) List findPendingPECEmailLogs(); diff --git a/src/main/java/net/gepafin/tendermanagement/service/PecMailService.java b/src/main/java/net/gepafin/tendermanagement/service/PecMailService.java index 2d7dbd30..77339aae 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/PecMailService.java +++ b/src/main/java/net/gepafin/tendermanagement/service/PecMailService.java @@ -8,7 +8,7 @@ import java.util.List; public interface PecMailService { - public PecMailResponse sendPecMail(HttpServletRequest request, List userActionIds); + public List sendPecMail(HttpServletRequest request, List userActionIds); public List getEmailLogByUserActionId(HttpServletRequest request, Long userActionId); diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/EmailService.java b/src/main/java/net/gepafin/tendermanagement/service/impl/EmailService.java index 395456e8..9f4f7e5d 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/EmailService.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/EmailService.java @@ -1,12 +1,13 @@ package net.gepafin.tendermanagement.service.impl; +import net.gepafin.tendermanagement.entities.EmailLogEntity; import net.gepafin.tendermanagement.model.request.EmailConfig; import net.gepafin.tendermanagement.model.request.EmailLogRequest; import java.util.List; public interface EmailService { - void sendEmail(String subject, String body, List recipientEmails, EmailConfig emailConfig, EmailLogRequest emailLogRequest); + void sendEmail(String subject, String body, List recipientEmails, EmailConfig emailConfig, EmailLogEntity emailLogEntity,Boolean isSendEmail); } diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/MailgunEmailService.java b/src/main/java/net/gepafin/tendermanagement/service/impl/MailgunEmailService.java index 978ea459..944ebda0 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/MailgunEmailService.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/MailgunEmailService.java @@ -8,6 +8,8 @@ import net.gepafin.tendermanagement.enums.EmailServiceTypeEnum; import net.gepafin.tendermanagement.enums.StatusTypeEnum; import net.gepafin.tendermanagement.model.request.EmailConfig; import net.gepafin.tendermanagement.model.request.EmailLogRequest; +import net.gepafin.tendermanagement.repositories.EmailLogRepository; +import net.gepafin.tendermanagement.util.DateTimeUtil; import net.gepafin.tendermanagement.util.Utils; import net.gepafin.tendermanagement.util.Validator; @@ -15,6 +17,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; +import java.time.LocalDateTime; import java.util.Base64; import java.util.List; @@ -30,8 +33,11 @@ public class MailgunEmailService implements EmailService { @Autowired private EmailLogDao emailLogDao; + @Autowired + private EmailLogRepository emailLogRepository; + @Override - public void sendEmail(String subject, String body, List recipientEmails, EmailConfig emailConfig, EmailLogRequest emailLogRequest) { + public void sendEmail(String subject, String body, List recipientEmails, EmailConfig emailConfig, EmailLogEntity emailLogEntity,Boolean isSendEmail) { if (Boolean.FALSE.equals(Boolean.parseBoolean(isEmailSendingEnabled))) { return; @@ -45,10 +51,8 @@ public class MailgunEmailService implements EmailService { // Send email via Mailgun API HttpResponse response2=null; if (Boolean.FALSE.equals(validator.isTestProfileActivated())) { - emailLogRequest.setEmailSubject(subject); - emailLogRequest.setEmailBody(body); - emailLogRequest.setSendStatus(StatusTypeEnum.SUCCESS.getValue()); - emailLogRequest.setRecipientEmails(Utils.listToCommaSeparatedString(recipientEmails)); + emailLogEntity.setSendStatus(StatusTypeEnum.SUCCESS.getValue()); + emailLogEntity.setRecipientEmails(Utils.listToCommaSeparatedString(recipientEmails)); try { Unirest.setTimeouts(0, 0); response2 = Unirest.post(url) @@ -60,16 +64,17 @@ public class MailgunEmailService implements EmailService { .field("html", body) .asString(); }catch(Exception e) { - emailLogRequest.setSendStatus(StatusTypeEnum.FAILED.getValue()); - emailLogRequest.setEmailServiceType(EmailServiceTypeEnum.MAILGUN_SERVICE); - emailLogRequest.setErrorMessage(e.getMessage()); - EmailLogEntity emailLogEntity= emailLogDao.createEmailLog(emailLogRequest); - throw new RuntimeException("Failed to send email via Mailgun: " + response2.getStatus()); + emailLogEntity.setSendStatus(StatusTypeEnum.FAILED.getValue()); + emailLogEntity.setEmailServiceType(EmailServiceTypeEnum.MAILGUN_SERVICE.getValue()); + emailLogEntity.setErrorMessage(e.getMessage()); + emailLogRepository.save(emailLogEntity); + throw new RuntimeException("Failed to send email via Mailgun: " + response2.getStatus()); } - emailLogRequest.setEmailServiceResponse(response2.getBody()); + emailLogEntity.setEmailServiceResponse(response2.getBody()); } - emailLogRequest.setEmailServiceType(EmailServiceTypeEnum.MAILGUN_SERVICE); - EmailLogEntity emailLogEntity= emailLogDao.createEmailLog(emailLogRequest); + emailLogEntity.setEmailServiceType(EmailServiceTypeEnum.MAILGUN_SERVICE.getValue()); + emailLogEntity.setSendDateTime(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); + emailLogRepository.save(emailLogEntity); } } 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 85153e91..f29750fc 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/PecEmailService.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/PecEmailService.java @@ -1,5 +1,6 @@ package net.gepafin.tendermanagement.service.impl; +import com.amazonaws.services.s3.AmazonS3Client; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.mashape.unirest.http.HttpResponse; @@ -9,14 +10,18 @@ import net.gepafin.tendermanagement.constants.GepafinConstant; import net.gepafin.tendermanagement.dao.ApplicationDao; import net.gepafin.tendermanagement.dao.EmailLogDao; import net.gepafin.tendermanagement.dao.NotificationDao; +import net.gepafin.tendermanagement.entities.ApplicationEntity; +import net.gepafin.tendermanagement.entities.CompanyEntity; +import net.gepafin.tendermanagement.entities.EmailLogEntity; import net.gepafin.tendermanagement.enums.EmailScenarioTypeEnum; import net.gepafin.tendermanagement.enums.EmailServiceTypeEnum; import net.gepafin.tendermanagement.enums.NotificationTypeEnum; import net.gepafin.tendermanagement.enums.StatusTypeEnum; -import net.gepafin.tendermanagement.model.request.EmailConfig; -import net.gepafin.tendermanagement.model.request.EmailLogRequest; -import net.gepafin.tendermanagement.model.request.NotificationReq; -import net.gepafin.tendermanagement.model.request.PecEmailRequest; +import net.gepafin.tendermanagement.model.request.*; +import net.gepafin.tendermanagement.repositories.EmailLogRepository; +import net.gepafin.tendermanagement.service.CompanyService; +import net.gepafin.tendermanagement.util.DateTimeUtil; +import net.gepafin.tendermanagement.util.S3DocxProcessor; import net.gepafin.tendermanagement.util.Utils; import net.gepafin.tendermanagement.util.Validator; @@ -25,6 +30,9 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.time.LocalDateTime; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -51,65 +59,109 @@ public class PecEmailService implements EmailService { @Autowired private ApplicationDao applicationDao; + @Autowired + private CompanyService companyService; + + @Autowired + private AmazonS3Client s3Client; + + @Autowired + private EmailLogRepository emailLogRepository; + @Override - public void sendEmail(String subject, String body, List recipientEmails, EmailConfig emailConfig, EmailLogRequest emailLogRequest) { + public void sendEmail(String subject, String body, List recipientEmails, EmailConfig emailConfig, EmailLogEntity emailLogEntity, Boolean isSendEmail) { if (Boolean.FALSE.equals(Boolean.parseBoolean(isEmailSendingEnabled))) { return; } + if(Boolean.TRUE.equals(isSendEmail)) { + Map replacements=new HashMap<>(); + List attachmentRequests =new ArrayList<>(); + S3DocxProcessor processor = new S3DocxProcessor(s3Client); + List urls = Utils.convertJsonStringToList(emailLogEntity.getAttachments(), String.class); - PecEmailRequest emailRequest = new PecEmailRequest(); - emailRequest.setSender(emailConfig.getSender()); - emailRequest.setSubject(subject); - 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(); - HttpResponse response2=null; - if (Boolean.FALSE.equals(validator.isTestProfileActivated())) { - emailLogRequest.setEmailSubject(emailRequest.getSubject()); - emailLogRequest.setEmailBody(emailRequest.getBody()); - emailLogRequest.setSendStatus(StatusTypeEnum.SUCCESS.getValue()); - emailLogRequest.setRecipientEmails(Utils.listToCommaSeparatedString(emailRequest.getRecipient())); - try { - if (Boolean.TRUE.equals(Boolean.parseBoolean(isPecServiceEnabled))) { - Unirest.setTimeouts(0, 0); - response2 = Unirest.post(url) - .header("Authorization", "Bearer " + authToken) - .header("Content-Type", "application/json") - .body(Utils.convertObjectToJson(emailRequest)) // Serialize the emailRequest object to JSON - .asString(); + if(emailLogEntity.getEmailType().equals(EmailScenarioTypeEnum.SPECIAL_APPLICATION_AMENDMENT_REQUESTED.getValue())) { + ApplicationEntity applicationEntity = applicationDao.validateApplication(emailLogEntity.getApplicationId()); + CompanyEntity company = companyService.validateCompany(applicationEntity.getCompanyId()); + String amount = Utils.convertToItalianFormat(String.valueOf(applicationEntity.getAmountAccepted())); + String protocolNumber = applicationEntity.getProtocol().getExternalProtocolNumber(); + if (protocolNumber == null) { + protocolNumber = String.valueOf(applicationEntity.getProtocol().getProtocolNumber()); + } + replacements = Map.of( + "{call_name}", applicationEntity.getCall().getName(), + "{amount_accepted}", amount, + "{pec}", "bandi.gepafin@legalmail.it", + "{company_name}", company.getCompanyName(), + "{protocol_number}", protocolNumber + ); + } + if (urls!=null && Boolean.FALSE.equals(urls.isEmpty())) { + 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); + } + } + PecEmailRequest emailRequest = new PecEmailRequest(); + emailRequest.setSender(emailConfig.getSender()); + emailRequest.setSubject(subject); + emailRequest.setBody(body); + emailRequest.setUsername(emailConfig.getUsername()); + emailRequest.setPassword(emailConfig.getPassword()); + emailRequest.setAttachments(attachmentRequests); + emailRequest.setRecipient(recipientEmails); + String url = emailConfig.getUrl() + GepafinConstant.PEC_SERVICE_SEND_MAIL; + String authToken = emailConfig.getAuthToken(); + HttpResponse response2 = null; + if (Boolean.FALSE.equals(validator.isTestProfileActivated())) { + emailLogEntity.setSendStatus(StatusTypeEnum.SUCCESS.getValue()); + emailLogEntity.setRecipientEmails(Utils.listToCommaSeparatedString(emailRequest.getRecipient())); + try { + if (Boolean.TRUE.equals(Boolean.parseBoolean(isPecServiceEnabled))) { + Unirest.setTimeouts(0, 0); + response2 = Unirest.post(url) + .header("Authorization", "Bearer " + authToken) + .header("Content-Type", "application/json") + .body(Utils.convertObjectToJson(emailRequest)) // Serialize the emailRequest object to JSON + .asString(); - if (!isSuccessfulPecResponse(response2.getBody())) { - String errorMsg = "PEC sending failed: " + response2.getBody(); - emailLogRequest.setSendStatus(StatusTypeEnum.FAILED.getValue()); - emailLogRequest.setEmailServiceType(EmailServiceTypeEnum.PEC_SERVICE); - emailLogRequest.setErrorMessage(errorMsg); - sendNotificationOnFailure(emailLogRequest.getUserId(),emailLogRequest.getEmailType()); + if (!isSuccessfulPecResponse(response2.getBody())) { + String errorMsg = "PEC sending failed: " + response2.getBody(); + emailLogEntity.setSendStatus(StatusTypeEnum.FAILED.getValue()); + emailLogEntity.setEmailServiceType(EmailServiceTypeEnum.PEC_SERVICE.getValue()); + emailLogEntity.setErrorMessage(errorMsg); + sendNotificationOnFailure(emailLogEntity.getUserId(), EmailScenarioTypeEnum.valueOf(emailLogEntity.getEmailType())); - if (EmailScenarioTypeEnum.SPECIAL_APPLICATION_AMENDMENT_REQUESTED.equals(emailLogRequest.getEmailType())) { - applicationDao.sendApplicationSubmissionFailureEmail(emailLogRequest); + if (EmailScenarioTypeEnum.APPLICATION_SUBMITTED.getValue().equals(emailLogEntity.getEmailType())) { + applicationDao.sendApplicationSubmissionFailureEmail(emailLogEntity); + } } } + } catch (Exception e) { + emailLogEntity.setSendStatus(StatusTypeEnum.FAILED.getValue()); + emailLogEntity.setEmailServiceType(EmailServiceTypeEnum.PEC_SERVICE.getValue()); + emailLogEntity.setErrorMessage(e.getMessage()); + sendNotificationOnFailure(emailLogEntity.getUserId(), EmailScenarioTypeEnum.valueOf(emailLogEntity.getEmailType())); + if (EmailScenarioTypeEnum.APPLICATION_SUBMITTED.getValue().equals(emailLogEntity.getEmailType())) { + applicationDao.sendApplicationSubmissionFailureEmail(emailLogEntity); + } } - }catch(Exception e) { - emailLogRequest.setSendStatus(StatusTypeEnum.FAILED.getValue()); - emailLogRequest.setEmailServiceType(EmailServiceTypeEnum.PEC_SERVICE); - emailLogRequest.setErrorMessage(e.getMessage()); - sendNotificationOnFailure(emailLogRequest.getUserId(),emailLogRequest.getEmailType()); - if (EmailScenarioTypeEnum.SPECIAL_APPLICATION_AMENDMENT_REQUESTED.equals(emailLogRequest.getEmailType())) { - applicationDao.sendApplicationSubmissionFailureEmail(emailLogRequest); + if (response2 != null) { + emailLogEntity.setEmailServiceResponse(response2.getBody()); } } - if(response2 != null) { - emailLogRequest.setEmailServiceResponse(response2.getBody()); - } } - emailLogRequest.setEmailServiceType(EmailServiceTypeEnum.PEC_SERVICE); - emailLogDao.createEmailLog(emailLogRequest); + emailLogEntity.setEmailServiceType(EmailServiceTypeEnum.PEC_SERVICE.getValue()); + emailLogEntity.setSendDateTime(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); + emailLogRepository.save(emailLogEntity); } private void sendNotificationOnFailure(Long userId, EmailScenarioTypeEnum emailScenarioTypeEnum) { diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/PecMailSerivceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/PecMailSerivceImpl.java index 507923be..8e0daef1 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/PecMailSerivceImpl.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/PecMailSerivceImpl.java @@ -17,7 +17,7 @@ public class PecMailSerivceImpl implements PecMailService { private PecMailDao pecMailDao; @Override - public PecMailResponse sendPecMail(HttpServletRequest request, List userActionIds) { + public List sendPecMail(HttpServletRequest request, List userActionIds) { return pecMailDao.sendPecMail(request,userActionIds); } diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/SystemEmailService.java b/src/main/java/net/gepafin/tendermanagement/service/impl/SystemEmailService.java index 0cc64b89..77593f2d 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/SystemEmailService.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/SystemEmailService.java @@ -9,6 +9,8 @@ import net.gepafin.tendermanagement.enums.EmailServiceTypeEnum; import net.gepafin.tendermanagement.enums.StatusTypeEnum; import net.gepafin.tendermanagement.model.request.EmailConfig; import net.gepafin.tendermanagement.model.request.EmailLogRequest; +import net.gepafin.tendermanagement.repositories.EmailLogRepository; +import net.gepafin.tendermanagement.util.DateTimeUtil; import net.gepafin.tendermanagement.util.Utils; import net.gepafin.tendermanagement.util.Validator; import org.slf4j.Logger; @@ -17,6 +19,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; +import java.time.LocalDateTime; import java.util.List; @Component @@ -43,42 +46,46 @@ public class SystemEmailService implements EmailService { @Autowired private EmailLogDao emailLogDao; + @Autowired + private EmailLogRepository emailLogRepository; + public final Logger log = LoggerFactory.getLogger(SystemEmailService.class); - public void sendEmail(String subject, String body, List recipientEmails, EmailConfig emailConfig, EmailLogRequest emailLogRequest) { + public void sendEmail(String subject, String body, List recipientEmails, EmailConfig emailConfig, EmailLogEntity emailLogEntity,Boolean isSendEmail) { if (Boolean.FALSE.equals(Boolean.parseBoolean(isEmailSendingEnabled))) { return; } + if (Boolean.TRUE.equals(isSendEmail)) { + emailLogEntity.setSendStatus(StatusTypeEnum.SUCCESS.getValue()); + emailLogEntity.setRecipientEmails(Utils.listToCommaSeparatedString(recipientEmails)); + emailLogEntity.setEmailServiceType(EmailServiceTypeEnum.SYSTEM_EMAIL_SERVICE.getValue()); + if (Boolean.FALSE.equals(validator.isTestProfileActivated())) { + MessageResponse response = null; + try { + MailgunMessagesApi mailgunMessagesApi = MailgunClient.config(mailGunBaseUrl, mailGunApiKey).createApi(MailgunMessagesApi.class); - emailLogRequest.setEmailSubject(subject); - emailLogRequest.setEmailBody(body); - emailLogRequest.setSendStatus(StatusTypeEnum.SUCCESS.getValue()); - emailLogRequest.setRecipientEmails(Utils.listToCommaSeparatedString(recipientEmails)); - emailLogRequest.setEmailServiceType(EmailServiceTypeEnum.SYSTEM_EMAIL_SERVICE); - if (Boolean.FALSE.equals(validator.isTestProfileActivated())) { - MessageResponse response = null; - try { - MailgunMessagesApi mailgunMessagesApi = MailgunClient.config(mailGunBaseUrl, mailGunApiKey).createApi(MailgunMessagesApi.class); + String mailFrom = mailGunUser; + com.mailgun.model.message.Message message = com.mailgun.model.message.Message.builder().from(mailFrom).to(recipientEmails).subject(subject).html(body).build(); - String mailFrom = mailGunUser; - com.mailgun.model.message.Message message = com.mailgun.model.message.Message.builder().from(mailFrom).to(recipientEmails).subject(subject).html(body).build(); + response = mailgunMessagesApi.sendMessage(mailGunDomainName, message); + } catch (Exception e) { + emailLogEntity.setSendStatus(StatusTypeEnum.FAILED.getValue()); + emailLogEntity.setEmailServiceType(EmailServiceTypeEnum.SYSTEM_EMAIL_SERVICE.getValue()); + emailLogEntity.setErrorMessage(e.getMessage()); + emailLogRepository.save(emailLogEntity); + throw new RuntimeException("Failed to send email via Mailgun: " + (response != null ? response.getMessage() : "No response from Mailgun"), e); + } + if (response != null) { + emailLogEntity.setEmailServiceResponse(response.toString()); + } - response = mailgunMessagesApi.sendMessage(mailGunDomainName, message); - } catch (Exception e) { - emailLogRequest.setSendStatus(StatusTypeEnum.FAILED.getValue()); - emailLogRequest.setEmailServiceType(EmailServiceTypeEnum.SYSTEM_EMAIL_SERVICE); - emailLogRequest.setErrorMessage(e.getMessage()); - emailLogDao.createEmailLog(emailLogRequest); - - throw new RuntimeException("Failed to send email via Mailgun: " + (response != null ? response.getMessage() : "No response from Mailgun"), e); } - if(response != null) { - emailLogRequest.setEmailServiceResponse(response.toString()); - } - - emailLogDao.createEmailLog(emailLogRequest); } + emailLogEntity.setEmailServiceType(EmailServiceTypeEnum.SYSTEM_EMAIL_SERVICE.getValue()); + emailLogEntity.setSendDateTime(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); + emailLogRepository.save(emailLogEntity); + } } diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/DashboardApi.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/DashboardApi.java index d0fb4bef..7812c0ad 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/DashboardApi.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/DashboardApi.java @@ -35,7 +35,7 @@ public interface DashboardApi { @ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) }) @GetMapping(value = "", produces = { "application/json" }) - @PreAuthorize("hasRole('ROLE_SUPER_ADMIN') || hasRole('ROLE_INSTRUCTOR_MANAGER')") + @PreAuthorize("hasRole('ROLE_SUPER_ADMIN') || hasRole('ROLE_INSTRUCTOR_MANAGER') || hasRole('ROLE_DIRECTOR')") ResponseEntity> getDashboardWidgetForSuperAdmin(HttpServletRequest request); @Operation(summary = "Api to get dashboard widget for beneficiary", diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/PecMailApi.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/PecMailApi.java index 34315491..27fdcc27 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/PecMailApi.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/PecMailApi.java @@ -28,7 +28,7 @@ public interface PecMailApi { @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = @ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE))) }) @PostMapping(value = "/userAction", produces = "application/json") - ResponseEntity> sendPecMail(HttpServletRequest request, + ResponseEntity>> sendPecMail(HttpServletRequest request, @Parameter(description = "The user action id", required = true) @RequestParam("userActionIds") List userActionIds); diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/PecMailController.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/PecMailController.java index ca3c7c35..41e8ed58 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/PecMailController.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/PecMailController.java @@ -33,14 +33,14 @@ public class PecMailController implements PecMailApi { private PecMailService pecMailService; @Override - public ResponseEntity> sendPecMail(HttpServletRequest request,List userActionIds) { + public ResponseEntity>> sendPecMail(HttpServletRequest request,List userActionIds) { loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.EMAIL) .actionContext(UserActionContextEnum.SEND_PEC_MAIL).build()); -// PecMailResponse pecMailResponse=pecMailService.sendPecMail(request,userActionId); + List pecMailResponse=pecMailService.sendPecMail(request,userActionIds); return ResponseEntity.status(HttpStatus.OK) - .body(new Response<>(null, Status.SUCCESS, Translator.toLocale(GepafinConstant.MAIL_SENT_SUCCESSFULLY))); + .body(new Response<>(pecMailResponse, Status.SUCCESS, Translator.toLocale(GepafinConstant.MAIL_SENT_SUCCESSFULLY))); } 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 178e4ad4..233604e3 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 @@ -3164,4 +3164,10 @@ + + + + + + From 52208a0c607007806f731f6a1a5e3051d3984b6a Mon Sep 17 00:00:00 2001 From: rajesh Date: Wed, 12 Nov 2025 14:45:41 +0530 Subject: [PATCH 72/75] Updated code for email scenarios --- .../tendermanagement/dao/EmailNotificationDao.java | 8 ++++---- .../service/impl/MailgunEmailService.java | 3 ++- .../tendermanagement/service/impl/PecEmailService.java | 4 +++- .../tendermanagement/service/impl/SystemEmailService.java | 3 ++- 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java index 8bf116aa..b778f662 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java @@ -423,10 +423,10 @@ public class EmailNotificationDao { HubEntity hubEntity = hubRepository.findById(hubId).orElseThrow(() -> new IllegalArgumentException("Invalid Hub ID: " + hubId)); if(Boolean.TRUE.equals(hubEntity.getUniqueUuid().equals(defaultHubUuid))){ - if(Boolean.FALSE.equals(emailLogEntity.getEmailType().equals(EmailScenarioTypeEnum.USER_CREATION.getValue())) - || Boolean.FALSE.equals(emailLogEntity.getEmailType().equals(EmailScenarioTypeEnum.APPLICATION_AMENDMENT_REMINDER.getValue())) - || Boolean.FALSE.equals(emailLogEntity.getEmailType().equals(EmailScenarioTypeEnum.APPLICATION_SUBMITTED.getValue())) - || Boolean.FALSE.equals(emailLogEntity.getEmailType().equals(EmailScenarioTypeEnum.PASSWORD_RESET_REQUEST.getValue()))) { + if(Boolean.TRUE.equals(emailLogEntity.getEmailType().equals(EmailScenarioTypeEnum.APPLICATION_TECHNICAL_EVALUATION_REJECTED.getValue())) + || Boolean.TRUE.equals(emailLogEntity.getEmailType().equals(EmailScenarioTypeEnum.APPLICATION_ADMISSIBLE.getValue())) + || Boolean.TRUE.equals(emailLogEntity.getEmailType().equals(EmailScenarioTypeEnum.APPLICATION_REJECTED.getValue())) + || Boolean.TRUE.equals(emailLogEntity.getEmailType().equals(EmailScenarioTypeEnum.APPLICATION_AMENDMENT_REQUESTED.getValue()))) { isSendEmail = Boolean.FALSE; } } diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/MailgunEmailService.java b/src/main/java/net/gepafin/tendermanagement/service/impl/MailgunEmailService.java index 944ebda0..d901abae 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/MailgunEmailService.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/MailgunEmailService.java @@ -51,6 +51,7 @@ public class MailgunEmailService implements EmailService { // Send email via Mailgun API HttpResponse response2=null; if (Boolean.FALSE.equals(validator.isTestProfileActivated())) { + emailLogEntity.setSendDateTime(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); emailLogEntity.setSendStatus(StatusTypeEnum.SUCCESS.getValue()); emailLogEntity.setRecipientEmails(Utils.listToCommaSeparatedString(recipientEmails)); try { @@ -64,6 +65,7 @@ public class MailgunEmailService implements EmailService { .field("html", body) .asString(); }catch(Exception e) { + emailLogEntity.setSendDateTime(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); emailLogEntity.setSendStatus(StatusTypeEnum.FAILED.getValue()); emailLogEntity.setEmailServiceType(EmailServiceTypeEnum.MAILGUN_SERVICE.getValue()); emailLogEntity.setErrorMessage(e.getMessage()); @@ -73,7 +75,6 @@ public class MailgunEmailService implements EmailService { emailLogEntity.setEmailServiceResponse(response2.getBody()); } emailLogEntity.setEmailServiceType(EmailServiceTypeEnum.MAILGUN_SERVICE.getValue()); - emailLogEntity.setSendDateTime(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); emailLogRepository.save(emailLogEntity); } 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 f29750fc..7f29d522 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/PecEmailService.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/PecEmailService.java @@ -122,6 +122,7 @@ public class PecEmailService implements EmailService { String authToken = emailConfig.getAuthToken(); HttpResponse response2 = null; if (Boolean.FALSE.equals(validator.isTestProfileActivated())) { + emailLogEntity.setSendDateTime(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); emailLogEntity.setSendStatus(StatusTypeEnum.SUCCESS.getValue()); emailLogEntity.setRecipientEmails(Utils.listToCommaSeparatedString(emailRequest.getRecipient())); try { @@ -135,6 +136,7 @@ public class PecEmailService implements EmailService { if (!isSuccessfulPecResponse(response2.getBody())) { String errorMsg = "PEC sending failed: " + response2.getBody(); + emailLogEntity.setSendDateTime(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); emailLogEntity.setSendStatus(StatusTypeEnum.FAILED.getValue()); emailLogEntity.setEmailServiceType(EmailServiceTypeEnum.PEC_SERVICE.getValue()); emailLogEntity.setErrorMessage(errorMsg); @@ -146,6 +148,7 @@ public class PecEmailService implements EmailService { } } } catch (Exception e) { + emailLogEntity.setSendDateTime(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); emailLogEntity.setSendStatus(StatusTypeEnum.FAILED.getValue()); emailLogEntity.setEmailServiceType(EmailServiceTypeEnum.PEC_SERVICE.getValue()); emailLogEntity.setErrorMessage(e.getMessage()); @@ -160,7 +163,6 @@ public class PecEmailService implements EmailService { } } emailLogEntity.setEmailServiceType(EmailServiceTypeEnum.PEC_SERVICE.getValue()); - emailLogEntity.setSendDateTime(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); emailLogRepository.save(emailLogEntity); } diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/SystemEmailService.java b/src/main/java/net/gepafin/tendermanagement/service/impl/SystemEmailService.java index 77593f2d..6a618d38 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/SystemEmailService.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/SystemEmailService.java @@ -57,6 +57,7 @@ public class SystemEmailService implements EmailService { return; } if (Boolean.TRUE.equals(isSendEmail)) { + emailLogEntity.setSendDateTime(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); emailLogEntity.setSendStatus(StatusTypeEnum.SUCCESS.getValue()); emailLogEntity.setRecipientEmails(Utils.listToCommaSeparatedString(recipientEmails)); emailLogEntity.setEmailServiceType(EmailServiceTypeEnum.SYSTEM_EMAIL_SERVICE.getValue()); @@ -70,6 +71,7 @@ public class SystemEmailService implements EmailService { response = mailgunMessagesApi.sendMessage(mailGunDomainName, message); } catch (Exception e) { + emailLogEntity.setSendDateTime(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); emailLogEntity.setSendStatus(StatusTypeEnum.FAILED.getValue()); emailLogEntity.setEmailServiceType(EmailServiceTypeEnum.SYSTEM_EMAIL_SERVICE.getValue()); emailLogEntity.setErrorMessage(e.getMessage()); @@ -83,7 +85,6 @@ public class SystemEmailService implements EmailService { } } emailLogEntity.setEmailServiceType(EmailServiceTypeEnum.SYSTEM_EMAIL_SERVICE.getValue()); - emailLogEntity.setSendDateTime(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); emailLogRepository.save(emailLogEntity); } From 53a9f2ae055634e012b55010910768de9b078732 Mon Sep 17 00:00:00 2001 From: rajesh Date: Thu, 13 Nov 2025 12:17:21 +0530 Subject: [PATCH 73/75] Fixed application status issue --- .../dao/ApplicationAmendmentRequestDao.java | 9 +++++++++ .../ApplicationAmendmentRequestRepository.java | 2 ++ 2 files changed, 11 insertions(+) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java index 66cb3ed7..b41f4621 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java @@ -380,6 +380,15 @@ public class ApplicationAmendmentRequestDao { //Set stop date time in the entity becuase amendment has started applicationEvaluationEntity.setStopDateTime(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); } + } + + boolean noneClosedOrExpired = amendmentRequest.stream() + .noneMatch(amendment -> + amendment.getStatus().equals(ApplicationAmendmentRequestEnum.CLOSE.getValue()) || + amendment.getStatus().equals(ApplicationAmendmentRequestEnum.EXPIRED.getValue()) + ); + + if(Boolean.TRUE.equals(noneClosedOrExpired)){ applicationEntity.setPreviousStatus(oldApplicationEntity.getStatus()); } diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationAmendmentRequestRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationAmendmentRequestRepository.java index d063eb37..3b0de711 100644 --- a/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationAmendmentRequestRepository.java +++ b/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationAmendmentRequestRepository.java @@ -73,6 +73,7 @@ public interface ApplicationAmendmentRequestRepository extends JpaRepository findEvaluationsWithoutActiveAmendmentsByIds(@Param("applicationEvaluationIds") Set applicationEvaluationIds); @@ -154,4 +155,5 @@ public interface ApplicationAmendmentRequestRepository extends JpaRepository statusList); + } From 57fcbf15ce7133fe3f10a016dedaddc66ee9916e Mon Sep 17 00:00:00 2001 From: rajesh Date: Thu, 13 Nov 2025 16:04:14 +0530 Subject: [PATCH 74/75] Updated application contract flow --- .../dao/ApplicationContractDao.java | 110 +++++++++--------- .../response/ApplicationContractResponse.java | 6 - .../service/ApplicationContractService.java | 4 +- .../impl/ApplicationContractServiceImpl.java | 26 ++--- .../web/rest/api/ApplicationContractApi.java | 33 +++--- .../ApplicationContractApiController.java | 22 ++-- 6 files changed, 100 insertions(+), 101 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationContractDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationContractDao.java index 44b7013a..0847b816 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationContractDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationContractDao.java @@ -65,7 +65,7 @@ public class ApplicationContractDao { @Autowired private AssignedApplicationsRepository assignedApplicationsRepository; - public ApplicationContractResponse createApplicationContract(Long applicationId, List contractDocuments, ApplicationContractRequest applicationContractRequest, UserEntity user) { + public ApplicationContractResponse createApplicationContract(Long applicationId, List contractDocuments,UserEntity user) { ApplicationEntity applicationEntity = applicationDao.validateApplication(applicationId); Optional optionalAssignedApplicationsEntity=assignedApplicationsRepository.findByApplicationIdAndIsDeletedFalse(applicationEntity.getId()); AssignedApplicationsEntity assignedApplicationsEntity=optionalAssignedApplicationsEntity.get(); @@ -73,19 +73,17 @@ public class ApplicationContractDao { if (Boolean.FALSE.equals(applicationEntity.getStatus().equals(ApplicationStatusTypeEnum.APPROVED.getValue()))) { throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.APPLICATION_NOT_APPROVED)); } - if (applicationContractRequest.getSubject() == null || applicationContractRequest.getText() == null) { - throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.SUBJECT_AND_BODY_REQUIRED)); - } ApplicationEntity oldApplicationData = Utils.getClonedEntityForData(applicationEntity); ApplicationContractEntity existingApplicationContractEntity = applicationContractRepository.findByApplicationIdAndIsDeletedFalse(applicationId); if (existingApplicationContractEntity != null) { throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.APPLICATION_CONTRACT_ALREADY_EXIST)); } - ApplicationContractEntity applicationContractEntity = createApplicationContractEntity(applicationContractRequest, user, applicationEntity); + ApplicationContractEntity applicationContractEntity = createApplicationContractEntity(user, applicationEntity); loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.INSERT).oldData(null).newData(applicationContractEntity).build()); - List documentResponseBeans = setContractDocuments(contractDocuments, user, applicationContractEntity); - applicationEntity.setStatus(ApplicationStatusTypeEnum.AWAITING_CONTRACT.getValue()); - assignedApplicationsEntity.setStatus(AssignedApplicationEnum.AWAITING_CONTRACT.getValue()); + List documentResponseBeans = setBeneficiaryContractDocuments(contractDocuments, user, applicationContractEntity); + applicationEntity.setStatus(ApplicationStatusTypeEnum.CONTRACT_SIGNED.getValue()); + assignedApplicationsEntity.setStatus(AssignedApplicationEnum.CONTRACT_SIGNED.getValue()); + applicationContractEntity.setCompletionDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); applicationRepository.save(applicationEntity); assignedApplicationsRepository.save(assignedApplicationsEntity); loggingUtil.addVersionHistory( @@ -93,18 +91,25 @@ public class ApplicationContractDao { loggingUtil.addVersionHistory( VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldAssignedApplicationEntity).newData(assignedApplicationsEntity).build()); UserEntity userEntity = userService.validateUser(applicationEntity.getUserId()); - emailNotificationDao.sendEmailForApplicationContracted(applicationEntity, applicationContractEntity, userEntity); - return createApplicationContractResponse(applicationContractEntity, documentResponseBeans, null,applicationEntity.getCall().getName()); + Map placeHolders = new HashMap<>(); + placeHolders.put("{{call_name}}", applicationEntity.getCall().getName()); + String protocolNumber = applicationEntity.getProtocol().getExternalProtocolNumber(); + if (protocolNumber == null) { + protocolNumber = String.valueOf(applicationEntity.getProtocol().getProtocolNumber()); + } + placeHolders.put("{{protocol_number}}", protocolNumber); + ApplicationEvaluationEntity applicationEvaluationEntity = applicationEvaluationDao.validateApplicationEvaluation(applicationEntity.getApplicationEvaluationId()); + + notificationDao.sendNotificationToInstructor(placeHolders, applicationEvaluationEntity, NotificationTypeEnum.CONTRACT_UPLOAD); + + return createApplicationContractResponse(applicationContractEntity, null, documentResponseBeans,applicationEntity.getCall().getName()); } private ApplicationContractResponse createApplicationContractResponse(ApplicationContractEntity applicationContractEntity, List instructorDocuments, List beneficiaryDocuments,String callName) { ApplicationContractResponse applicationContractResponse = new ApplicationContractResponse(); applicationContractResponse.setId(applicationContractEntity.getId()); - applicationContractResponse.setText(applicationContractEntity.getText()); - applicationContractResponse.setSubject(applicationContractEntity.getSubject()); applicationContractResponse.setInstructorId(applicationContractEntity.getInstructorId()); applicationContractResponse.setStatus(ApplicationContractStatusEnum.valueOf(applicationContractEntity.getStatus())); - applicationContractResponse.setInstructorDocuments(instructorDocuments); applicationContractResponse.setBeneficiaryDocuments(beneficiaryDocuments); applicationContractResponse.setCompletionDate(applicationContractEntity.getCompletionDate()); applicationContractResponse.setBeneficiaryUserId(applicationContractEntity.getBeneficiaryUserId()); @@ -126,15 +131,13 @@ public class ApplicationContractDao { return documentResponseBeans; } - private ApplicationContractEntity createApplicationContractEntity(ApplicationContractRequest applicationContractRequest, UserEntity user, ApplicationEntity applicationEntity) { + private ApplicationContractEntity createApplicationContractEntity(UserEntity user, ApplicationEntity applicationEntity) { ApplicationContractEntity applicationContractEntity = new ApplicationContractEntity(); - applicationContractEntity.setSubject(applicationContractRequest.getSubject()); - applicationContractEntity.setText(applicationContractRequest.getText()); applicationContractEntity.setApplicationId(applicationEntity.getId()); applicationContractEntity.setInstructorId(user.getId()); applicationContractEntity.setIsDeleted(Boolean.FALSE); applicationContractEntity.setApplicationId(applicationEntity.getId()); - applicationContractEntity.setStatus(ApplicationContractStatusEnum.DRAFT.getValue()); + applicationContractEntity.setStatus(ApplicationContractStatusEnum.SIGNED.getValue()); applicationContractEntity.setBeneficiaryUserId(applicationEntity.getUserId()); applicationContractRepository.save(applicationContractEntity); return applicationContractEntity; @@ -147,40 +150,40 @@ public class ApplicationContractDao { return new ArrayList<>(); } - public ApplicationContractResponse updateApplicationContract(Long applicationContractId, List beneficiaryContractDocuments, UserEntity user) { - ApplicationContractEntity applicationContractEntity = validateApplicationContract(applicationContractId); - ApplicationContractEntity oldApplicationContract = Utils.getClonedEntityForData(applicationContractEntity); - applicationContractEntity.setCompletionDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); - applicationContractEntity.setStatus(ApplicationContractStatusEnum.SIGNED.getValue()); - List beneficiaryContractDocuments1 = setBeneficiaryContractDocuments(beneficiaryContractDocuments, user, applicationContractEntity); - List documentResponseBeans = applicationAmendmentRequestDao.getDocumentResponseBean(applicationContractEntity.getInstructorDocument()); - loggingUtil.addVersionHistory( - VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplicationContract).newData(applicationContractEntity).build()); - ApplicationEntity applicationEntity = applicationDao.validateApplication(applicationContractEntity.getApplicationId()); - ApplicationEntity oldApplicationData = Utils.getClonedEntityForData(applicationEntity); - Optional optionalAssignedApplicationsEntity=assignedApplicationsRepository.findByApplicationIdAndIsDeletedFalse(applicationEntity.getId()); - AssignedApplicationsEntity assignedApplicationsEntity=optionalAssignedApplicationsEntity.get(); - AssignedApplicationsEntity oldAssignedApplicationEntity=Utils.getClonedEntityForData(assignedApplicationsEntity); - ApplicationEvaluationEntity applicationEvaluationEntity = applicationEvaluationDao.validateApplicationEvaluation(applicationEntity.getApplicationEvaluationId()); - applicationEntity.setStatus(ApplicationStatusTypeEnum.CONTRACT_SIGNED.getValue()); - assignedApplicationsEntity.setStatus(AssignedApplicationEnum.CONTRACT_SIGNED.getValue()); - applicationRepository.save(applicationEntity); - assignedApplicationsRepository.save(assignedApplicationsEntity); - loggingUtil.addVersionHistory( - VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplicationData).newData(applicationEntity).build()); - loggingUtil.addVersionHistory( - VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldAssignedApplicationEntity).newData(assignedApplicationsEntity).build()); - Map placeHolders = new HashMap<>(); - placeHolders.put("{{call_name}}", applicationEntity.getCall().getName()); - String protocolNumber = applicationEntity.getProtocol().getExternalProtocolNumber(); - if (protocolNumber == null) { - protocolNumber = String.valueOf(applicationEntity.getProtocol().getProtocolNumber()); - } - placeHolders.put("{{protocol_number}}", protocolNumber); - notificationDao.sendNotificationToInstructor(placeHolders, applicationEvaluationEntity, NotificationTypeEnum.CONTRACT_UPLOAD); - - return createApplicationContractResponse(applicationContractEntity, documentResponseBeans, beneficiaryContractDocuments1,applicationEntity.getCall().getName()); - } +// public ApplicationContractResponse updateApplicationContract(Long applicationContractId, List beneficiaryContractDocuments, UserEntity user) { +// ApplicationContractEntity applicationContractEntity = validateApplicationContract(applicationContractId); +// ApplicationContractEntity oldApplicationContract = Utils.getClonedEntityForData(applicationContractEntity); +// applicationContractEntity.setCompletionDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); +// applicationContractEntity.setStatus(ApplicationContractStatusEnum.SIGNED.getValue()); +// List beneficiaryContractDocuments1 = setBeneficiaryContractDocuments(beneficiaryContractDocuments, user, applicationContractEntity); +// List documentResponseBeans = applicationAmendmentRequestDao.getDocumentResponseBean(applicationContractEntity.getInstructorDocument()); +// loggingUtil.addVersionHistory( +// VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplicationContract).newData(applicationContractEntity).build()); +// ApplicationEntity applicationEntity = applicationDao.validateApplication(applicationContractEntity.getApplicationId()); +// ApplicationEntity oldApplicationData = Utils.getClonedEntityForData(applicationEntity); +// Optional optionalAssignedApplicationsEntity=assignedApplicationsRepository.findByApplicationIdAndIsDeletedFalse(applicationEntity.getId()); +// AssignedApplicationsEntity assignedApplicationsEntity=optionalAssignedApplicationsEntity.get(); +// AssignedApplicationsEntity oldAssignedApplicationEntity=Utils.getClonedEntityForData(assignedApplicationsEntity); +// ApplicationEvaluationEntity applicationEvaluationEntity = applicationEvaluationDao.validateApplicationEvaluation(applicationEntity.getApplicationEvaluationId()); +// applicationEntity.setStatus(ApplicationStatusTypeEnum.CONTRACT_SIGNED.getValue()); +// assignedApplicationsEntity.setStatus(AssignedApplicationEnum.CONTRACT_SIGNED.getValue()); +// applicationRepository.save(applicationEntity); +// assignedApplicationsRepository.save(assignedApplicationsEntity); +// loggingUtil.addVersionHistory( +// VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplicationData).newData(applicationEntity).build()); +// loggingUtil.addVersionHistory( +// VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldAssignedApplicationEntity).newData(assignedApplicationsEntity).build()); +// Map placeHolders = new HashMap<>(); +// placeHolders.put("{{call_name}}", applicationEntity.getCall().getName()); +// String protocolNumber = applicationEntity.getProtocol().getExternalProtocolNumber(); +// if (protocolNumber == null) { +// protocolNumber = String.valueOf(applicationEntity.getProtocol().getProtocolNumber()); +// } +// placeHolders.put("{{protocol_number}}", protocolNumber); +// notificationDao.sendNotificationToInstructor(placeHolders, applicationEvaluationEntity, NotificationTypeEnum.CONTRACT_UPLOAD); +// +// return createApplicationContractResponse(applicationContractEntity, documentResponseBeans, beneficiaryContractDocuments1,applicationEntity.getCall().getName()); +// } public ApplicationContractEntity validateApplicationContract(Long applicationContractId) { ApplicationContractEntity applicationContractEntity = applicationContractRepository.findByIdAndIsDeletedFalse(applicationContractId); @@ -198,8 +201,11 @@ public class ApplicationContractDao { String contractDocumentId = contractDocumentIds.stream() .map(String::valueOf) .collect(Collectors.joining(",")); + ApplicationContractEntity oldApplicationContractEntity = Utils.getClonedEntityForData(applicationContractEntity); applicationContractEntity.setBeneficiaryDocument(contractDocumentId); applicationContractRepository.save(applicationContractEntity); + loggingUtil.addVersionHistory( + VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplicationContractEntity).newData(applicationContractEntity).build()); return documentResponseBeans; } @@ -227,7 +233,7 @@ public class ApplicationContractDao { public List getContractByBeneficiaryUserId(UserEntity user) { - List applicationContractEntities = applicationContractRepository.findByBeneficiaryUserIdAndStatusAndIsDeletedFalse(user.getId(), ApplicationContractStatusEnum.DRAFT.getValue()); + List applicationContractEntities = applicationContractRepository.findByBeneficiaryUserIdAndStatusAndIsDeletedFalse(user.getId(), ApplicationContractStatusEnum.SIGNED.getValue()); if (applicationContractEntities.isEmpty()) { return null; } diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationContractResponse.java b/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationContractResponse.java index a90d1204..5ea30071 100644 --- a/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationContractResponse.java +++ b/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationContractResponse.java @@ -11,14 +11,8 @@ public class ApplicationContractResponse { private Long id; - private String subject; - - private String text; - private ApplicationContractStatusEnum status; - private List instructorDocuments; - private Long instructorId; private List beneficiaryDocuments; diff --git a/src/main/java/net/gepafin/tendermanagement/service/ApplicationContractService.java b/src/main/java/net/gepafin/tendermanagement/service/ApplicationContractService.java index bf562cdf..b1012aba 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/ApplicationContractService.java +++ b/src/main/java/net/gepafin/tendermanagement/service/ApplicationContractService.java @@ -9,9 +9,9 @@ import java.util.List; public interface ApplicationContractService { - public ApplicationContractResponse createApplicationContract(HttpServletRequest httpServletRequest, Long applicationId, List contractDocuments, ApplicationContractRequest applicationContractRequest); + public ApplicationContractResponse createApplicationContract(HttpServletRequest httpServletRequest, Long applicationId, List beneficiaryContractDocuments); - public ApplicationContractResponse updateApplicationContract(HttpServletRequest httpServletRequest, Long applicationContractId,List beneficiaryContractDocuments); +// public ApplicationContractResponse updateApplicationContract(HttpServletRequest httpServletRequest, Long applicationContractId,List beneficiaryContractDocuments); public ApplicationContractResponse getContractById(Long contractId); diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationContractServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationContractServiceImpl.java index 5e1ea5c0..3953a3ad 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationContractServiceImpl.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationContractServiceImpl.java @@ -33,23 +33,23 @@ public class ApplicationContractServiceImpl implements ApplicationContractServic private UserDao userDao; @Override - public ApplicationContractResponse createApplicationContract(HttpServletRequest httpServletRequest, Long applicationId, List contractDocuments, ApplicationContractRequest applicationContractRequest) { - UserEntity user= validator.validateUser(httpServletRequest); - if(contractDocuments==null) { - throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.FILES_REQUIRED_FOR_CONTRACT)); - } - contractDocuments.forEach(Utils::validateFileType); - return applicationContractDao.createApplicationContract(applicationId,contractDocuments,applicationContractRequest,user); - } - - @Override - public ApplicationContractResponse updateApplicationContract(HttpServletRequest httpServletRequest, Long applicationContractId, List beneficiaryContractDocuments) { + public ApplicationContractResponse createApplicationContract(HttpServletRequest httpServletRequest, Long applicationId, List beneficiaryContractDocuments) { UserEntity user= validator.validateUser(httpServletRequest); if(beneficiaryContractDocuments==null) { - throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.FILES_REQUIRED_FOR_CONTRACT)); + throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.FILES_REQUIRED_FOR_CONTRACT)); } - return applicationContractDao.updateApplicationContract(applicationContractId,beneficiaryContractDocuments,user); + beneficiaryContractDocuments.forEach(Utils::validateFileType); + return applicationContractDao.createApplicationContract(applicationId,beneficiaryContractDocuments,user); } +// +// @Override +// public ApplicationContractResponse updateApplicationContract(HttpServletRequest httpServletRequest, Long applicationContractId, List beneficiaryContractDocuments) { +// UserEntity user= validator.validateUser(httpServletRequest); +// if(beneficiaryContractDocuments==null) { +// throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.FILES_REQUIRED_FOR_CONTRACT)); +// } +// return applicationContractDao.updateApplicationContract(applicationContractId,beneficiaryContractDocuments,user); +// } @Override public ApplicationContractResponse getContractById(Long contractId) { diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/ApplicationContractApi.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/ApplicationContractApi.java index 350aa2ac..d4f59db8 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/ApplicationContractApi.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/ApplicationContractApi.java @@ -36,26 +36,25 @@ public interface ApplicationContractApi { @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { @ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) }) @PostMapping(value = "/application/{applicationId}", produces = "application/json", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) - @PreAuthorize("hasRole('ROLE_SUPER_ADMIN') || hasRole('ROLE_INSTRUCTOR_MANAGER')|| hasRole('ROLE_PRE_INSTRUCTOR')") + @PreAuthorize( "hasRole('ROLE_SUPER_ADMIN') || hasRole('ROLE_BENEFICIARY') || hasRole('ROLE_CONFIDI')") ResponseEntity> createApplicationContract(HttpServletRequest request, @Parameter(description = "Application ID", required = true) @PathVariable("applicationId") Long applicationId, @Parameter(description = "List of files to upload", required = true) - @RequestPart(required = true) List contractDocuments, - @Parameter(description = "Application Contract Request Body", required = true) @RequestPart ApplicationContractRequest applicationContractRequest); + @RequestPart(required = true) List beneficiaryContractDocuments); - @Operation(summary = "Api to update application contract from beneficiary side", - 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) })) }) - @PutMapping(value = "{applicationContractId}", produces = "application/json", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) - @PreAuthorize( "hasRole('ROLE_SUPER_ADMIN') || hasRole('ROLE_BENEFICIARY') || hasRole('ROLE_CONFIDI')") - ResponseEntity> updateApplicationContract(HttpServletRequest request, - @Parameter(description = "Application Contract ID", required = true) @PathVariable("applicationContractId") Long applicationContractId, @Parameter(description = "List of files to upload", required = true) - @RequestPart(required = true) List beneficiaryContractDocuments); +// @Operation(summary = "Api to update application contract from beneficiary side", +// 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) })) }) +// @PutMapping(value = "{applicationContractId}", produces = "application/json", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) +// @PreAuthorize( "hasRole('ROLE_SUPER_ADMIN') || hasRole('ROLE_BENEFICIARY') || hasRole('ROLE_CONFIDI')") +// ResponseEntity> updateApplicationContract(HttpServletRequest request, +// @Parameter(description = "Application Contract ID", required = true) @PathVariable("applicationContractId") Long applicationContractId, @Parameter(description = "List of files to upload", required = true) +// @RequestPart(required = true) List beneficiaryContractDocuments); @Operation(summary = "Api to get an application contract by id", responses = { diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/ApplicationContractApiController.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/ApplicationContractApiController.java index 4d5227e9..3766c48b 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/ApplicationContractApiController.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/ApplicationContractApiController.java @@ -33,25 +33,25 @@ public class ApplicationContractApiController implements ApplicationContractApi private ApplicationContractService applicationContractService; @Override - public ResponseEntity> createApplicationContract(HttpServletRequest request, Long applicationId, List contractDocuments, ApplicationContractRequest applicationContractRequest) { + public ResponseEntity> createApplicationContract(HttpServletRequest request, Long applicationId, List beneficiaryContractDocuments) { loggingUtil.logUserAction( UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.INSERT).actionContext(UserActionContextEnum.CREATE_CONTRACT_FOR_APPLICATION).build()); - ApplicationContractResponse applicationContractResponse=applicationContractService.createApplicationContract(request,applicationId,contractDocuments,applicationContractRequest); + ApplicationContractResponse applicationContractResponse=applicationContractService.createApplicationContract(request,applicationId,beneficiaryContractDocuments); return ResponseEntity.status(HttpStatus.OK) .body(new Response<>(applicationContractResponse, Status.SUCCESS, Translator.toLocale(GepafinConstant.CREATE_APPLICATION_CONTRACT))); } - @Override - public ResponseEntity> updateApplicationContract(HttpServletRequest request, Long applicationId, List beneficiaryContractDocuments) { - loggingUtil.logUserAction( - UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.UPDATE).actionContext(UserActionContextEnum.UPDATE_APPLICATION_CONTRACT).build()); - ApplicationContractResponse applicationContractResponse=applicationContractService.updateApplicationContract(request,applicationId,beneficiaryContractDocuments); - - return ResponseEntity.status(HttpStatus.OK) - .body(new Response<>(applicationContractResponse, Status.SUCCESS, Translator.toLocale(GepafinConstant.APPLICATION_CONTRACT_UPDATED))); - } +// @Override +// public ResponseEntity> updateApplicationContract(HttpServletRequest request, Long applicationId, List beneficiaryContractDocuments) { +// loggingUtil.logUserAction( +// UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.UPDATE).actionContext(UserActionContextEnum.UPDATE_APPLICATION_CONTRACT).build()); +// ApplicationContractResponse applicationContractResponse=applicationContractService.updateApplicationContract(request,applicationId,beneficiaryContractDocuments); +// +// return ResponseEntity.status(HttpStatus.OK) +// .body(new Response<>(applicationContractResponse, Status.SUCCESS, Translator.toLocale(GepafinConstant.APPLICATION_CONTRACT_UPDATED))); +// } @Override public ResponseEntity> getApplicationContractById(HttpServletRequest request, Long id) { From 326ce77e8c08e56c0add87416335b195ab18df79 Mon Sep 17 00:00:00 2001 From: rajesh Date: Fri, 14 Nov 2025 18:53:25 +0530 Subject: [PATCH 75/75] Done ticket GEPAFINBE-6147 & contract document issue --- .../constants/GepafinConstant.java | 1 + .../dao/ApplicationAmendmentRequestDao.java | 28 ++++++++++++------- .../tendermanagement/dao/ApplicationDao.java | 2 +- ...ApplicationAmendmentRequestRepository.java | 2 +- src/main/resources/message_en.properties | 3 ++ src/main/resources/message_it.properties | 2 ++ 6 files changed, 26 insertions(+), 12 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java b/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java index 452ecb50..cf544480 100644 --- a/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java +++ b/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java @@ -633,6 +633,7 @@ public class GepafinConstant { public static final String SUBJECT_AND_BODY_REQUIRED="subject.body.required"; public static final String MAIL_SENT_SUCCESSFULLY="mail.send.successfully"; public static final String EMAIL_LOG_FETCHED="email.log.fetched"; + public static final String APPLICATION_AMENDMENT_APPROPIATE_STATUS="amendment.appropiate.status"; } diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java index b41f4621..d8243429 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java @@ -1130,8 +1130,12 @@ public class ApplicationAmendmentRequestDao { public ApplicationAmendmentRequestResponse closeAmendmentRequest(Long id, CloseAmendmentRequest closeAmendmentRequest) { log.info("Closing application amendement with ID: {}", id); - ApplicationAmendmentRequestEntity existingApplicationAmendment = validatApplicationAmendmentRequestByListStatus(id,List.of(ApplicationAmendmentRequestEnum.AWAITING.getValue(),ApplicationAmendmentRequestEnum.RESPONSE_RECEIVED.getValue())); + ApplicationAmendmentRequestEntity existingApplicationAmendment = validateApplicationAmendmentRequest(id); //cloned entity for old data and versioning + if(Boolean.TRUE.equals(existingApplicationAmendment.getStatus().equals(ApplicationAmendmentRequestEnum.CLOSE.getValue())) + || Boolean.TRUE.equals(existingApplicationAmendment.getStatus().equals(ApplicationAmendmentRequestEnum.EXPIRED.getValue()))) { + throw new CustomValidationException(Status.VALIDATION_ERROR,Translator.toLocale(GepafinConstant.APPLICATION_AMENDMENT_APPROPIATE_STATUS)); + } ApplicationAmendmentRequestEntity oldApplicationAmendmentEntity = Utils.getClonedEntityForData(existingApplicationAmendment); List amendmentRequestList = applicationAmendmentRequestRepository.findAllByApplicationEvaluationIdAndIsDeletedFalse( existingApplicationAmendment.getApplicationEvaluationEntity().getId() @@ -1215,7 +1219,11 @@ public class ApplicationAmendmentRequestDao { public ApplicationAmendmentRequestResponse extendResponseDays(Long id, Long newResponseDays) { log.info("Extending response days for Application Amendment ID: {}, Additional Days: {}", id, newResponseDays); - ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity = validatApplicationAmendmentRequestByStatus(id,ApplicationAmendmentRequestEnum.EXPIRED.getValue()); + ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity = validateApplicationAmendmentRequest(id); + if(Boolean.TRUE.equals(applicationAmendmentRequestEntity.getStatus().equals(ApplicationAmendmentRequestEnum.CLOSE.getValue())) + || Boolean.TRUE.equals(applicationAmendmentRequestEntity.getStatus().equals(ApplicationAmendmentRequestEnum.AWAITING.getValue()))) { + throw new CustomValidationException(Status.VALIDATION_ERROR,Translator.toLocale(GepafinConstant.APPLICATION_AMENDMENT_APPROPIATE_STATUS)); + } log.info("Extending response days for Application Amendment ID: {}, Additional Days: {}", id, newResponseDays); if (newResponseDays != null && newResponseDays > 0) { @@ -1777,14 +1785,14 @@ public class ApplicationAmendmentRequestDao { amendment.setEmailSendResponse(mergedResponses); applicationAmendmentRequestRepository.save(amendment); } - public ApplicationAmendmentRequestEntity validatApplicationAmendmentRequestByListStatus(Long id,List status) { - ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity = applicationAmendmentRequestRepository.findByIdAndIsDeletedFalseAndStatusIn(id, status); - if (applicationAmendmentRequestEntity == null) { - throw new ResourceNotFoundException(Status.NOT_FOUND, - Translator.toLocale(GepafinConstant.APPLICATION_AMENDMENT_NOT_FOUND_MSG)); - } - return applicationAmendmentRequestEntity; - } +// public ApplicationAmendmentRequestEntity validatApplicationAmendmentRequestByListStatus(Long id,List status) { +// ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity = applicationAmendmentRequestRepository.findByIdAndIsDeletedFalse(id, status); +// if (applicationAmendmentRequestEntity == null) { +// throw new ResourceNotFoundException(Status.NOT_FOUND, +// Translator.toLocale(GepafinConstant.APPLICATION_AMENDMENT_NOT_FOUND_MSG)); +// } +// return applicationAmendmentRequestEntity; +// } public long calculateSuspendedDays(List amendments) { List> periods = amendments.stream() .filter(amendmentRequest -> amendmentRequest.getStartDate() != null) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java index bfc0e4d5..d193c953 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java @@ -1688,7 +1688,7 @@ public class ApplicationDao { for (DocumentEntity contractDocument : contractDocuments) { ApplicationContractEntity applicationContractEntity=applicationContractRepository.findByIdAndIsDeletedFalse(contractDocument.getSourceId()); String contractFolder = "CONTRACT/"; - String contractS3Folder = s3PathConfig.generateDocumentPath(DocumentSourceTypeEnum.CONTRACT, callId, applicationId, 0L,contractDocument.getSourceId(),applicationContractEntity.getApplicationId()); + String contractS3Folder = s3PathConfig.generateDocumentPath(DocumentSourceTypeEnum.CONTRACT, callId, applicationId, 0L,0L,applicationContractEntity.getId()); String fileName = Utils.extractFileName(contractDocument.getFilePath()); addDocumentToZip(zos, contractS3Folder, contractDocument.getFilePath(), contractFolder + fileName); } diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationAmendmentRequestRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationAmendmentRequestRepository.java index 3b0de711..dc03dd43 100644 --- a/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationAmendmentRequestRepository.java +++ b/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationAmendmentRequestRepository.java @@ -59,7 +59,7 @@ public interface ApplicationAmendmentRequestRepository extends JpaRepository findAmendmentsDueForExpiration(LocalDateTime currentTime); diff --git a/src/main/resources/message_en.properties b/src/main/resources/message_en.properties index a2aeca61..825dbc63 100644 --- a/src/main/resources/message_en.properties +++ b/src/main/resources/message_en.properties @@ -425,3 +425,6 @@ application.contract.already.exist=Application contract already exist for this a application.not.approved=Application is not approved. subject.body.required=Subject and body is required to create contract. mail.send.successfully=Mail sent succesfully. +email.log.fetched=Email log fetched successfully. +amendment.appropiate.status=Application amendment is not in appropiate status for this operation. + diff --git a/src/main/resources/message_it.properties b/src/main/resources/message_it.properties index 8507f202..0b059428 100644 --- a/src/main/resources/message_it.properties +++ b/src/main/resources/message_it.properties @@ -416,3 +416,5 @@ application.contract.already.exist=Il contratto di applicazione esiste gi application.not.approved=La domanda non stata approvata. subject.body.required=Per creare un contratto sono necessari oggetto e corpo. mail.send.successfully=Email inviata con successo. +email.log.fetched=Registro email recuperato correttamente. +amendment.appropiate.status=L'emendamento dell'applicazione non in stato appropriato per questa operazione.