From c7c21cf90d37d243bcf1bf8fed46fd42c7b0b3b2 Mon Sep 17 00:00:00 2001 From: rajesh Date: Fri, 27 Jun 2025 20:04:39 +0530 Subject: [PATCH 01/18] 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/18] 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/18] 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/18] 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/18] 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/18] 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/18] 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/18] 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/18] 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/18] 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/18] 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/18] 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/18] 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/18] 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 517a8da925a55aded78f0e0bdf4a40a458ec7e76 Mon Sep 17 00:00:00 2001 From: rajesh Date: Tue, 29 Jul 2025 17:44:07 +0530 Subject: [PATCH 15/18] 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 16/18] 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 17/18] 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 18/18] 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);