diff --git a/pom.xml b/pom.xml
index a42534bf..daa067ba 100644
--- a/pom.xml
+++ b/pom.xml
@@ -251,6 +251,24 @@
0.4.8
+
+ org.apache.commons
+ commons-csv
+ 1.10.0
+
+
+
+
+
+
+
+
+ com.sun.mail
+ jakarta.mail
+ 2.0.1
+
+
+
@@ -271,8 +289,8 @@
liquibase-maven-plugin
src/main/resources/application.properties
-
-
-
+
+
+
diff --git a/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java b/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java
index edc85e28..57139e52 100644
--- a/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java
+++ b/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java
@@ -510,6 +510,68 @@ public class GepafinConstant {
public static final String APPLICATION_USER_ID="applicationUserId";
public static final String INVALID_USER_ID="invalid.user";
public static final String COMPANY_NAME="companyName";
+ public static final String TABLE_COLUMNS="table_columns";
+ public static final String PREDEFINED="predefined";
+ public static final String EBABLE_CSV="enableCsv";
+ public static final String LABEL_CSV="labelCsv";
+ public static final String GET="get";
+ public static final String REPORT_COLUMNS="reportColumns";
+ public static final String FIELD_TYPE="fieldtype";
+ public static final String ENABLE_FORMULA="enableFormula";
+ public static final String STATE_FIELD_DATA="stateFieldData";
+ public static final String REPORT_ENABLE="reportEnable";
+ public static final String TABLE="table";
+ public static final String GET_FIELD_TYPE="getFieldType";
+ public static final String GET_APPLICATION_FORM_ID="getApplicationFormId";
+ public static final String GET_APPLICATION_ID="getApplicationId";
+ public static final String GET_ID="getId";
+ public static final String GET_CLASS="getClass";
+ public static final String GET_FORM_ID="getFormId";
+ public static final String GET_FIELD_ID="getFieldId";
+ public static final String GET_FIELD_LABEL="getFieldLabel";
+ public static final String GET_FIELD_VALUE="getFieldValue";
+ public static final String GET_REPORT_ENABLE="getReportEnable";
+ public static final String GET_REPORT_HEADER="getReportHeader";
+
+ public static final String APPOINTMENT_ID="appointmentId";
+ public static final String APPLICATION_STATUS="applicationStatus";
+
+ public static final String RINALDO_EMAIL = "rinaldo.bonazzo@bflows.net";
+ public static final String RESEND_EMAIL_SENT_SUCCESS_MSG = "resend.email.sent.success.msg";
+ public static final String RESEND_EMAIL_SENT_FAILED_MSG = "resend.email.sent.failed.msg";
+ public static final String REMINDER_EMAIL_FAILED_MSG = "reminder.email.sent.failed.msg";
+
+ public static final String READMIT_APPLICATION_SUCCESS = "application.readmit.success";
+
+ public static final String NO_EMAIL_LOG_FOUND = "no.email.log.msg";
+ public static final String USER_ACTION_ID_NOT_FOUND = "user.action.id.not.found";
+
+ public static final String CAUSE_STRING = "cause" ;
+ public static final String ERROR_DESCRIPTION_STRING = "errorDescription" ;
+ public static final String ERROR_STRING = "errors";
+ public static final String PROTOCOL_SERVICE_URL="http://65.108.55.96:8080";
+ public static final String PROTOCOL_SERVICE_BEARER_TOKEN="/auth/login";
+ public static final String PROTOCOL_SERVICE_CREATE_PROTOCOL="/documenti/protocollaUD";
+ public static final String PROTOCOL_CALL_NAME="BANDO";
+ public static final String PROTOCOL_DOC_URL="DOC_URL";
+ public static final String PROTOCOL_COMPANY_NAME_VAT_NUMBER="OGGETTO_PG";
+ public static final String PROTOCOL_DOC_HASH="URL_CONTENT_HASH";
+ public static final String PROTOCOL_TIPO_PROTOCOLLAZIONE="TIPO_PROTOCOLLAZIONE";
+ public static final String PROTOCOL_TIPO_CORRISPONDENTE_COMPANY="tipoCorrispondente";
+ public static final String PROTOCOL_COMPANY_NAME="denominazione";
+ public static final String PROTOCOL_MEZZO="mezzo";
+ public static final String PROTOCOL_INDIRIZZO_PEC="indirizzoPec";
+ public static final String PROTOCOL_COMPANY_VAT_NUMBER="identificativo";
+ public static final String PROTOCOL_CODICE_UO="codiceUo";
+ public static final String PROTOCOL_COMPETENTE="competente";
+ public static final String PROTOCOL_TIPO_CORRISPONDENTE="tipoCorrispondente";
+ public static final String PROTOCOL_MITTENTE="mittente";
+ public static final String PROTOCOL_DESTINATARI="destinatari";
+ public static final String PROTOCOL_EXTERNAL_YEAR="ANNO_PG";
+ public static final String PROTOCOL_EXTERNAL_NUMBER="NUM_PG";
+ public static final String PROTOCOL_EXTERNAL_DATE="DATA_PG_DT";
+ public static final String PROTOCOL_DOC_SUFFIX="#noauth";
+
}
diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java
index daa4391b..0cded205 100644
--- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java
+++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java
@@ -1,5 +1,6 @@
package net.gepafin.tendermanagement.dao;
+import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.persistence.criteria.CriteriaBuilder;
@@ -26,6 +27,7 @@ import net.gepafin.tendermanagement.web.rest.api.errors.ResourceNotFoundExceptio
import net.gepafin.tendermanagement.web.rest.api.errors.Status;
import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.tuple.Pair;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
@@ -140,6 +142,12 @@ public class ApplicationAmendmentRequestDao {
@Autowired
private ApplicationDao applicationDao;
+ @Autowired
+ private EmailLogRepository emailLogRepository;
+
+ @Autowired
+ private EmailDao emailDao;
+
public ApplicationAmendmentRequestResponse getApplicationDataForAmendment(Long applicationEvaluationId) {
log.info("Fetching the application data for the Amendment process {}", applicationEvaluationId);
ApplicationEvaluationEntity applicationEvaluationEntity = applicationEvaluationService.validateApplicationEvaluation(applicationEvaluationId);
@@ -151,7 +159,8 @@ public class ApplicationAmendmentRequestDao {
String file=applicationEvaluationEntity.getFile();
String checkList=applicationEvaluationEntity.getChecklist();
if(file != null){
- evaluationFileRequests=Utils.convertJsonStringToList(file,FieldRequest.class);
+ log.info("Parsing evaluation file data for evaluationId={}", applicationEvaluationId);
+ evaluationFileRequests=Utils.convertJsonStringToList(file,FieldRequest.class);
}
if(applicationEvaluationEntity.getEvaluationVersion().equals(EvaluationVersionEnum.V1.getValue())) {
checklistValidationForEvaluationV1(evaluationFileRequests, checkList, checklistRequests);
@@ -300,6 +309,15 @@ public class ApplicationAmendmentRequestDao {
log.info("Application submitted successfully for amendment", applicationAmendmentRequestResponse);
if (Boolean.TRUE.equals(applicationAmendmentRequestResponse.getIsSendEmail())) {
emailNotificationDao.sendMailToNotifyBeneficiaryRegardingNewAmendment(applicationAmendmentRequestEntity);
+ EmailSendResponse emailSendResponse = emailDao.buildEmailSendResponseFromRequest(request);
+ List responses = List.of(emailSendResponse);
+ if (!Boolean.TRUE.equals(emailSendResponse.getIsEmailSend())){
+ saveEmailSendResponse(emailSendResponse, applicationAmendmentRequestEntity);
+ applicationAmendmentRequestResponse.setEmailSendResponse(responses);
+ }
+ else{
+ applicationAmendmentRequestResponse.setEmailSendResponse(Collections.emptyList());
+ }
}
return applicationAmendmentRequestResponse;
}
@@ -309,6 +327,7 @@ public class ApplicationAmendmentRequestDao {
applicationAmendmentRequestEntity.setNote(applicationAmendmentRequest.getNote());
applicationAmendmentRequestEntity.setResponseDays(applicationAmendmentRequest.getResponseDays());
if(applicationAmendmentRequest.getResponseDays()==null || applicationAmendmentRequest.getResponseDays() < 0){
+ log.warn("Invalid responseDays received: {}", applicationAmendmentRequest.getResponseDays());
throw new CustomValidationException(Status.BAD_REQUEST,Translator.toLocale(GepafinConstant.RESPONSE_DAYS_NOT_NULL));
}
applicationAmendmentRequestEntity.setEndDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now()).plusDays(applicationAmendmentRequest.getResponseDays()));
@@ -359,8 +378,11 @@ public class ApplicationAmendmentRequestDao {
ProtocolEntity protocolEntity = protocolDao.createProtocolEntity(
applicationEvaluationEntity.getAssignedApplicationsEntity().getApplication(), protocolNumber,
userEntity.getHub().getId(),false);
+ protocolDao.saveProtocolEntity(protocolEntity);
applicationAmendmentRequestEntity.setProtocol(protocolEntity);
ApplicationAmendmentRequestEntity applicationAmendment = saveApplicationAmendmentRequestEntity(applicationAmendmentRequestEntity, null, VersionActionTypeEnum.INSERT);
+ log.info("Amendment request saved with ID={}", applicationAmendment.getId());
+
String evaluationStatusType = applicationEvaluationEntity.getStatus();
if (Boolean.FALSE.equals(evaluationStatusType.equals((ApplicationEvaluationStatusTypeEnum.SOCCORSO.getValue())))){
// applicationEvaluationEntity.setStatus(ApplicationEvaluationStatusTypeEnum.SOCCORSO.getValue());
@@ -399,7 +421,7 @@ public class ApplicationAmendmentRequestDao {
loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldAssignedApplication).newData(assignedApplicationsEntity).build());
}
-
+ log.info("Amendment creation process completed successfully for applicationId={}, evaluationId={}", applicationId, applicationEvaluationId);
return applicationAmendment;
}
private void setAmendmentDocuments(String amendmentNotes, String amendmentFieldRequest,
@@ -490,7 +512,7 @@ public class ApplicationAmendmentRequestDao {
}
public DocumentResponseBean createDocumentResponseBean(String documentId) {
-
+ log.info("Initiating document response creation for documentId={}", documentId);
if (!StringUtils.isEmpty(documentId)) {
Optional documentEntity = documentRepository.findByIdAndNotDeleted(Long.valueOf(documentId));
if(documentEntity.isPresent()){
@@ -506,6 +528,7 @@ public class ApplicationAmendmentRequestDao {
Long hubId = applicationEntity.getHubId();
HubEntity hubEntity = hubService.valdateHub(hubId);
+ response.setEmailSendResponse(entity.getEmailSendResponse());
response.setId(entity.getId());
response.setApplicationId(entity.getApplicationId());
response.setApplicationEvaluationId(entity.getApplicationEvaluationEntity().getId());
@@ -647,13 +670,15 @@ public class ApplicationAmendmentRequestDao {
public ApplicationAmendmentRequestResponse getApplicationAmendmentRequestById(Long id) {
log.info("Fetching application amendment with ID: {}", id);
ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity = validateApplicationAmendmentRequest(id);
- ApplicationAmendmentRequestResponse response = convertEntityToResponse(applicationAmendmentRequestEntity,true);
- log.info("Application Amendment fetched successfully by ID: {}", response);
- return response;
+ ApplicationAmendmentRequestResponse response = convertEntityToResponse(applicationAmendmentRequestEntity,true);
+ response.setEmailSendResponse(applicationAmendmentRequestEntity.getEmailSendResponse());
+ return response;
}
public List getAllApplicationAmendmentRequest(HttpServletRequest request, Long userId) {
+ log.info("Entering getAllApplicationAmendmentRequest with userId={}", userId);
if (validator.checkIsPreInstructor() && userId == null) {
+ log.warn("Access denied: Pre-instructor must provide userId for amendment request retrieval.");
throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.USER_ID_NOT_NULL_MSG));
}
if (userId != null) {
@@ -696,9 +721,11 @@ public class ApplicationAmendmentRequestDao {
isBeneficiary=true;
}
if(Boolean.TRUE.equals(isBeneficiary) && existingApplicationAmendment.getStatus().equals(ApplicationAmendmentRequestEnum.RESPONSE_RECEIVED.getValue())){
- throw new CustomValidationException(Status.VALIDATION_ERROR,Translator.toLocale(GepafinConstant.PERMISSION_DENIED));
+ log.warn("Permission denied: Beneficiary tried to update amendment ID {} with status RESPONSE_RECEIVED", id);
+ throw new CustomValidationException(Status.VALIDATION_ERROR,Translator.toLocale(GepafinConstant.PERMISSION_DENIED));
}
if(Boolean.FALSE.equals(isBeneficiary) && existingApplicationAmendment.getStatus().equals(ApplicationAmendmentRequestEnum.AWAITING.getValue())){
+ log.warn("Permission denied: Non-beneficiary tried to update amendment ID {} with status AWAITING", id);
throw new CustomValidationException(Status.VALIDATION_ERROR,Translator.toLocale(GepafinConstant.PERMISSION_DENIED));
}
@@ -721,10 +748,12 @@ public class ApplicationAmendmentRequestDao {
}
existingApplicationAmendment.setUpdatedDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now()));
if(updateRequest.getAmendmentDocuments()!=null && Boolean.FALSE.equals(updateRequest.getAmendmentDocuments().isEmpty())) {
+ log.debug("Setting amendment documents for amendment ID: {}", id);
setAmendmentDocuments(updateRequest.getAmendmentNotes(),updateRequest.getAmendmentDocuments(), existingApplicationAmendment);
}
ApplicationAmendmentRequestEntity updatedApplicationAmendment = saveApplicationAmendmentRequestEntity(existingApplicationAmendment,oldApplicationAmendmentEntity,VersionActionTypeEnum.UPDATE);
ApplicationAmendmentRequestResponse response = convertEntityToResponse(updatedApplicationAmendment,false);
+ log.info("Successfully updated ApplicationAmendmentRequest with ID: {}", id);
log.info("Application Amendment updated successfully: {}", response);
return response;
}
@@ -1020,6 +1049,7 @@ public class ApplicationAmendmentRequestDao {
public List getAllAmendmentRequestByBeneficiaryId(Long beneficiaryUserId) {
+ log.info("Fetching all amendment requests for beneficiaryUserId={}", beneficiaryUserId);
UserEntity userEntity = userService.validateUser(beneficiaryUserId);
List entities =
applicationAmendmentRequestRepository.findByUserId(beneficiaryUserId);
@@ -1032,29 +1062,34 @@ public class ApplicationAmendmentRequestDao {
public ApplicationAmendmentRequestResponse closeAmendmentRequest(Long id, CloseAmendmentRequest closeAmendmentRequest) {
log.info("Closing application amendement with ID: {}", id);
- ApplicationAmendmentRequestEntity existingApplicationAmendment = validateApplicationAmendmentRequest(id);
+ ApplicationAmendmentRequestEntity existingApplicationAmendment = validatApplicationAmendmentRequestByListStatus(id,List.of(ApplicationAmendmentRequestEnum.AWAITING.getValue(),ApplicationAmendmentRequestEnum.RESPONSE_RECEIVED.getValue()));
//cloned entity for old data and versioning
ApplicationAmendmentRequestEntity oldApplicationAmendmentEntity = Utils.getClonedEntityForData(existingApplicationAmendment);
List amendmentRequestList = applicationAmendmentRequestRepository.findAllByApplicationEvaluationIdAndIsDeletedFalse(
existingApplicationAmendment.getApplicationEvaluationEntity().getId()
);
+ log.debug("Found {} amendment requests for ApplicationEvaluationId={}", amendmentRequestList.size(), existingApplicationAmendment.getApplicationEvaluationEntity().getId());
+
// Check if this is the last amendment being closed
boolean isLastRemaining = amendmentRequestList.stream()
.filter(amendment -> !amendment.getId().equals(id)) // Exclude the current amendment
- .allMatch(amendment -> amendment.getStatus().equals(ApplicationAmendmentRequestEnum.CLOSE.getValue()));
+ .allMatch(amendment -> amendment.getStatus().equals(ApplicationAmendmentRequestEnum.CLOSE.getValue()) || amendment.getStatus().equals(ApplicationAmendmentRequestEnum.EXPIRED.getValue()));
+
- if (isLastRemaining) {
- log.info("The current amendment is the last remaining one to be closed.");
- applicationAmendmentRequestDao.calculateEndDateAndSuspensionDays(existingApplicationAmendment.getApplicationEvaluationEntity());
- }
setIfUpdated(existingApplicationAmendment::getInternalNote, existingApplicationAmendment::setInternalNote, closeAmendmentRequest.getInternalNote());
setIfUpdated(existingApplicationAmendment::getStatus, existingApplicationAmendment::setStatus, ApplicationAmendmentRequestEnum.CLOSE.getValue());
existingApplicationAmendment.setClosingDate(LocalDateTime.now());
ApplicationAmendmentRequestEntity updatedApplicationAmendment = saveApplicationAmendmentRequestEntity(existingApplicationAmendment, oldApplicationAmendmentEntity,
VersionActionTypeEnum.UPDATE);
+ if (isLastRemaining) {
+ log.info("The current amendment is the last remaining one to be closed.");
+ applicationAmendmentRequestDao.calculateEndDateAndSuspensionDaysOnExpirationOrClosing(existingApplicationAmendment.getApplicationEvaluationEntity());
+ }
ApplicationAmendmentRequestResponse response = convertEntityToResponse(updatedApplicationAmendment,false);
+ log.info("Updated amendment status to CLOSE for amendment ID: {}", id);
+
List amendmentRequests = applicationAmendmentRequestRepository.findAllByApplicationEvaluationIdAndIsDeletedFalse(
existingApplicationAmendment.getApplicationEvaluationEntity().getId());
Boolean allClosed = amendmentRequests.stream().allMatch(amendment -> (amendment.getStatus().equals(ApplicationAmendmentRequestEnum.CLOSE.getValue()) || amendment.getStatus().equals(ApplicationAmendmentRequestEnum.EXPIRED.getValue())));
@@ -1062,24 +1097,28 @@ public class ApplicationAmendmentRequestDao {
ApplicationEntity oldApplicationEntityData = Utils.getClonedEntityForData(application);
if (Boolean.TRUE.equals(allClosed)) {
existingApplicationAmendment.getApplicationEvaluationEntity().setStatus(ApplicationEvaluationStatusTypeEnum.OPEN.getValue());
-
if (allClosed) {
ApplicationEvaluationEntity existingApplicationEvaluationEntity = existingApplicationAmendment.getApplicationEvaluationEntity();
ApplicationEvaluationEntity oldApplicationEvaluationEntity = Utils.getClonedEntityForData(existingApplicationEvaluationEntity);
existingApplicationEvaluationEntity.setStatus(ApplicationEvaluationStatusTypeEnum.OPEN.getValue());
applicationEvaluationRepository.save(existingApplicationAmendment.getApplicationEvaluationEntity());
+ log.info("Updated ApplicationEvaluation status to OPEN for ID: {}", existingApplicationEvaluationEntity.getId());
application.setStatus(ApplicationStatusTypeEnum.EVALUATION.getValue());
applicationRepository.save(application);
+ log.info("Updated Application status to EVALUATION for Application ID: {}", application.getId());
+
existingApplicationAmendment.getApplicationEvaluationEntity().getAssignedApplicationsEntity().setStatus(AssignedApplicationEnum.OPEN.getValue());
AssignedApplicationsEntity assignedApplicationsEntity = assignedApplicationsDao.validateAssignedApplication(
existingApplicationAmendment.getApplicationEvaluationEntity().getAssignedApplicationsEntity().getId());
AssignedApplicationsEntity oldAssignedApplicationData = Utils.getClonedEntityForData(assignedApplicationsEntity);
- assignedApplicationsEntity = assignedApplicationsRepository.save(existingApplicationAmendment.getApplicationEvaluationEntity().getAssignedApplicationsEntity());
+ existingApplicationAmendment.getApplicationEvaluationEntity().getAssignedApplicationsEntity().setStatus(AssignedApplicationEnum.OPEN.getValue());
+ assignedApplicationsEntity = assignedApplicationsRepository.save(existingApplicationAmendment.getApplicationEvaluationEntity().getAssignedApplicationsEntity());
+ log.info("Updated AssignedApplication status to OPEN for ID: {}", assignedApplicationsEntity.getId());
Map placeHolders = notificationDao.sendNotificationToBeneficiary(application, NotificationTypeEnum.AMENDMENT_CLOSED);
@@ -1104,15 +1143,18 @@ public class ApplicationAmendmentRequestDao {
return response;
}
-
public ApplicationAmendmentRequestResponse extendResponseDays(Long id, Long newResponseDays) {
- ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity = validateApplicationAmendmentRequest(id);
+ log.info("Extending response days for Application Amendment ID: {}, Additional Days: {}", id, newResponseDays);
+ ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity = validatApplicationAmendmentRequestByStatus(id,ApplicationAmendmentRequestEnum.EXPIRED.getValue());
if (newResponseDays != null && newResponseDays > 0) {
- ApplicationAmendmentRequestEntity oldApplicationAmendmentEntity = Utils.getClonedEntityForData(applicationAmendmentRequestEntity);
+ ApplicationAmendmentRequestEntity oldApplicationAmendmentEntity = Utils.getClonedEntityForData(applicationAmendmentRequestEntity);
Long currentResponseDays = applicationAmendmentRequestEntity.getResponseDays() != null ? applicationAmendmentRequestEntity.getResponseDays() : 0L;
applicationAmendmentRequestEntity.setResponseDays(currentResponseDays + newResponseDays);
- applicationAmendmentRequestEntity.setEndDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now().plusDays(applicationAmendmentRequestEntity.getResponseDays())));
+ applicationAmendmentRequestEntity.setEndDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now().plusDays(newResponseDays)));
+ applicationAmendmentRequestEntity.setStatus(ApplicationAmendmentRequestEnum.AWAITING.getValue());
+ applicationAmendmentRequestEntity.getApplicationEvaluationEntity().setStatus(ApplicationEvaluationStatusTypeEnum.SOCCORSO.getValue());
+ applicationAmendmentRequestEntity.getApplicationEvaluationEntity().getAssignedApplicationsEntity().getApplication().setStatus(ApplicationStatusTypeEnum.SOCCORSO.getValue());
applicationAmendmentRequestRepository.save(applicationAmendmentRequestEntity);
/** This code is responsible for adding a version history log for the "Update Application Amendment" operation. **/
@@ -1156,6 +1198,7 @@ public class ApplicationAmendmentRequestDao {
ApplicationAmendmentRequestEntity existingApplicationAmendment = validateApplicationAmendmentRequest(id);
ApplicationAmendmentRequestEntity oldApplicationAmendmentEntity = Utils.getClonedEntityForData(existingApplicationAmendment);
if (Boolean.TRUE.equals(existingApplicationAmendment.getStatus().equals(ApplicationAmendmentRequestEnum.AWAITING.getValue())) && Boolean.TRUE.equals(statusTypeEnum.equals(ApplicationAmendmentRequestEnum.RESPONSE_RECEIVED))) {
+ log.info("Updating amendment ID {} status from {} to {}", id, existingApplicationAmendment.getStatus(), statusTypeEnum);
existingApplicationAmendment.setStatus(ApplicationAmendmentRequestEnum.RESPONSE_RECEIVED.getValue());
existingApplicationAmendment.setUpdatedDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now()));
applicationAmendmentRequestRepository.save(existingApplicationAmendment);
@@ -1168,12 +1211,15 @@ public class ApplicationAmendmentRequestDao {
return response;
}
- public void sendReminderEmail(Long amendmentId) {
-
+ public EmailReminderResponse sendReminderEmail(Long amendmentId) {
+ log.info("Initiating reminder email process for Amendment ID: {}", amendmentId);
ApplicationAmendmentRequestEntity amendment = applicationAmendmentRequestRepository.findByIdAndIsDeletedFalse(amendmentId)
- .orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.APPLICATION_AMENDMENT_NOT_FOUND_MSG)));
+ .orElseThrow(() -> { log.error("Amendment not found with ID: {}", amendmentId);
+ return new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.APPLICATION_AMENDMENT_NOT_FOUND_MSG));
+ });
Optional entityOptional = applicationEvaluationRepository.findByIdAndIsDeletedFalse(amendment.getApplicationEvaluationEntity().getId());
+ EmailReminderResponse emailReminderResponse = new EmailReminderResponse();
if (entityOptional.isPresent()) {
ApplicationEntity applicationEntity = applicationService.validateApplication(entityOptional.get().getApplicationId());
UserEntity beneficiaryUser = userService.validateUser(applicationEntity.getUserId());
@@ -1183,13 +1229,26 @@ public class ApplicationAmendmentRequestDao {
String body = prepareBody(emailTemplate, amendment, beneficiaryUser);
String email = beneficiaryUser.getEmail();
if (Boolean.TRUE.equals(amendment.getIsEmail()) && email != null && !email.isEmpty()) {
+ log.info("Sending reminder email to: {}", email);
EmailLogRequest emailLogRequest = emailLogDao.createEmailLogRequest(emailTemplate.getEmailScenario(), RecipientTypeEnum.USER, beneficiaryUser.getId(), email,
beneficiaryUser.getId(), applicationEntity.getId(), amendment.getId(), applicationEntity.getCall().getId());
emailNotificationDao.sendMail(hub.getId(), subject, body, List.of(email), emailLogRequest);
+ EmailSendResponse emailSendResponse = emailDao.buildEmailSendResponseFromRequest(request);
+ List responses = List.of(emailSendResponse);
+ if (!Boolean.TRUE.equals(emailSendResponse.getIsEmailSend())){
+ emailReminderResponse.setEmailSendResponse(responses);
+ saveEmailSendResponse(emailSendResponse, amendment);
+ }
+ else{
+ emailReminderResponse.setEmailSendResponse(Collections.emptyList());
+ }
+ log.info("Reminder email sent successfully for Amendment ID: {}", amendmentId);
} else {
+ log.warn("Beneficiary email not found or isEmail flag is false for Amendment ID: {}", amendmentId);
throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.BENEFICIARY_EMAIL_NOT_FOUND_MSG));
}
}
+ return emailReminderResponse;
}
private String prepareSubject(SystemEmailTemplateResponse template, ApplicationAmendmentRequestEntity amendment, UserEntity beneficiary) {
@@ -1219,26 +1278,26 @@ public class ApplicationAmendmentRequestDao {
return Utils.replacePlaceholders(template.getHtmlContent(), bodyPlaceholders);
}
- public ApplicationEvaluationEntity calculateEndDateAndSuspensionDays(ApplicationEvaluationEntity applicationEvaluationEntity){
- LocalDateTime currentDate=DateTimeUtil.DateServerToUTC(LocalDateTime.now());
- LocalDateTime endDate=currentDate.plusDays(applicationEvaluationEntity.getRemainingDays());
- Long suspendedDays = ChronoUnit.DAYS.between(applicationEvaluationEntity.getStopDateTime(), currentDate);
-
- ApplicationEvaluationEntity oldApplicationEvaluationEntity = Utils.getClonedEntityForData(applicationEvaluationEntity);
- applicationEvaluationEntity.setEndDate(endDate);
- if(applicationEvaluationEntity.getSuspendedDays() == null) {
- applicationEvaluationEntity.setSuspendedDays(0L);
- }
- applicationEvaluationEntity.setSuspendedDays(applicationEvaluationEntity.getSuspendedDays()+suspendedDays);
- ApplicationEvaluationEntity applicationEvaluation = applicationEvaluationRepository.save(applicationEvaluationEntity);
-
- /** This code is responsible for adding a version history log for the "Update Application Amendment" operation. **/
- loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplicationEvaluationEntity).newData(applicationEvaluation).build());
-
- return applicationEvaluation;
-
-
- }
+// public ApplicationEvaluationEntity calculateEndDateAndSuspensionDays(ApplicationEvaluationEntity applicationEvaluationEntity){
+// LocalDateTime currentDate=DateTimeUtil.DateServerToUTC(LocalDateTime.now());
+// LocalDateTime endDate=currentDate.plusDays(applicationEvaluationEntity.getRemainingDays());
+// Long suspendedDays = ChronoUnit.DAYS.between(applicationEvaluationEntity.getStopDateTime(), currentDate);
+//
+// ApplicationEvaluationEntity oldApplicationEvaluationEntity = Utils.getClonedEntityForData(applicationEvaluationEntity);
+// applicationEvaluationEntity.setEndDate(endDate);
+// if(applicationEvaluationEntity.getSuspendedDays() == null) {
+// applicationEvaluationEntity.setSuspendedDays(0L);
+// }
+// applicationEvaluationEntity.setSuspendedDays(applicationEvaluationEntity.getSuspendedDays()+suspendedDays);
+// ApplicationEvaluationEntity applicationEvaluation = applicationEvaluationRepository.save(applicationEvaluationEntity);
+//
+// /** This code is responsible for adding a version history log for the "Update Application Amendment" operation. **/
+// loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplicationEvaluationEntity).newData(applicationEvaluation).build());
+//
+// return applicationEvaluation;
+//
+//
+// }
private GetAllAmendmentResponseBean initializeGetAllBasicResponse(ApplicationAmendmentRequestEntity entity) {
GetAllAmendmentResponseBean response = new GetAllAmendmentResponseBean();
@@ -1271,7 +1330,9 @@ public class ApplicationAmendmentRequestDao {
return response;
}
private void softDeleteDocument(Long documentId) {
+ log.info("Initiating soft delete for Document ID: {}", documentId);
documentService.deleteFile(documentId);
+ log.info("Document ID: {} soft deleted successfully.", documentId);
}
// public PageableResponseBean> getApplicationAmendmentByPaginnation(Long userId, ApplicationAmendmentPaginationRequestBean applicationAmendmentPaginationRequestBean) {
@@ -1390,6 +1451,7 @@ public class ApplicationAmendmentRequestDao {
// }
public PageableResponseBean> getApplicationAmendmentByPaginationByView(Long userId, ApplicationAmendmentPaginationRequestBean applicationAmendmentPaginationRequestBean) {
+ log.info("Fetching paginated application amendments for userId: {}", userId);
Integer pageNo = null;
Integer pageLimit = null;
if (applicationAmendmentPaginationRequestBean.getGlobalFilters() != null) {
@@ -1421,6 +1483,7 @@ public class ApplicationAmendmentRequestDao {
pageableResponseBean.setTotalRecords(entityPage.getTotalElements());
pageableResponseBean.setPageSize(entityPage.getSize());
+ log.info("Paginated response prepared successfully for userId: {}", userId);
return pageableResponseBean;
}
public Specification searchPaginationByView(Long userId,ApplicationAmendmentPaginationRequestBean applicationAmendmentPaginationRequestBean) {
@@ -1452,6 +1515,7 @@ public class ApplicationAmendmentRequestDao {
private List getPredicatesByView(ApplicationAmendmentPaginationRequestBean amendmentPaginationRequestBean,
CriteriaBuilder criteriaBuilder, Root root,Long userId) {
+ log.info("Building predicates for userId: {}", userId);
Integer year = null;
String search = null;
Map filters = new HashMap<>();
@@ -1471,6 +1535,7 @@ public class ApplicationAmendmentRequestDao {
LocalDateTime startOfYear = LocalDateTime.of(filterYear, 1, 1, 0, 0);
LocalDateTime endOfYear = LocalDateTime.of(filterYear, 12, 31, 23, 59, 59);
+ log.debug("Filtering by year between {} and {}", startOfYear, endOfYear);
// Add the range comparison to filter records within the year
predicates.add(criteriaBuilder.between(root.get(GepafinConstant.CREATED_DATE), startOfYear, endOfYear));
@@ -1539,8 +1604,111 @@ public class ApplicationAmendmentRequestDao {
applicationAmendmentRequestViewResponse.setExpirationDate(applicationAmendmentRequestView.getExpirationDate());
applicationAmendmentRequestViewResponse.setAssigendUserName(applicationAmendmentRequestView.getAssigendUserName());
applicationAmendmentRequestViewResponse.setStatus(applicationAmendmentRequestView.getStatus());
+ applicationAmendmentRequestViewResponse.setEmailSendResponse(applicationAmendmentRequestView.getEmailSendResponse());
return applicationAmendmentRequestViewResponse;
}
+ public ApplicationEvaluationEntity calculateEndDateAndSuspensionDaysOnExpirationOrClosing
+ (ApplicationEvaluationEntity applicationEvaluationEntity) {
+
+ // Fetch all linked amendments
+ List amendments =
+ applicationAmendmentRequestRepository.findAllByApplicationEvaluationIdAndIsDeletedFalse(applicationEvaluationEntity.getId());
+
+ // Recalculate suspension
+ long suspendedDays = calculateSuspendedDays(amendments);
+
+ // Update end date and save
+
+ ApplicationEvaluationEntity oldEntity = Utils.getClonedEntityForData(applicationEvaluationEntity);
+ HubEntity hub = hubService.valdateHub(applicationEvaluationEntity.getAssignedApplicationsEntity().getApplication().getHubId());
+ Long initialDays = (hub != null) ? hub.getEvaluationExpirationDays() : 30L;
+ LocalDateTime endDate = applicationEvaluationEntity.getStartDate().plusDays(suspendedDays+initialDays);
+ applicationEvaluationEntity.setEndDate(endDate);
+ applicationEvaluationEntity.setSuspendedDays(suspendedDays);
+ ApplicationEvaluationEntity updated = applicationEvaluationRepository.save(applicationEvaluationEntity);
+
+ loggingUtil.addVersionHistory(VersionHistoryRequest.builder()
+ .request(request)
+ .actionType(VersionActionTypeEnum.UPDATE)
+ .oldData(oldEntity)
+ .newData(updated)
+ .build());
+
+ 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 ApplicationAmendmentRequestEntity validatApplicationAmendmentRequestByStatus(Long id,String status) {
+ ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity = applicationAmendmentRequestRepository.findByIdAndIsDeletedFalseAndStatus(id, status);
+ if (applicationAmendmentRequestEntity == null) {
+ throw new ResourceNotFoundException(Status.NOT_FOUND,
+ Translator.toLocale(GepafinConstant.APPLICATION_AMENDMENT_NOT_FOUND_MSG));
+ }
+ return applicationAmendmentRequestEntity;
+ }
+ private void saveEmailSendResponse(EmailSendResponse newResponses, ApplicationAmendmentRequestEntity amendment) {
+ List mergedResponses = Utils.mergeEmailSendResponses(amendment.getEmailSendResponse(), newResponses);
+
+ amendment.setEmailSendResponse(mergedResponses);
+ applicationAmendmentRequestRepository.save(amendment);
+ }
+ public ApplicationAmendmentRequestEntity validatApplicationAmendmentRequestByListStatus(Long id,List status) {
+ ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity = applicationAmendmentRequestRepository.findByIdAndIsDeletedFalseAndStatusIn(id, status);
+ if (applicationAmendmentRequestEntity == null) {
+ throw new ResourceNotFoundException(Status.NOT_FOUND,
+ Translator.toLocale(GepafinConstant.APPLICATION_AMENDMENT_NOT_FOUND_MSG));
+ }
+ return applicationAmendmentRequestEntity;
+ }
}
diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java
index 66b3e818..098249b7 100644
--- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java
+++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java
@@ -1,10 +1,15 @@
package net.gepafin.tendermanagement.dao;
import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
+import com.itextpdf.text.BaseColor;
+import com.itextpdf.text.Font;
+import com.itextpdf.text.FontFactory;
import jakarta.persistence.criteria.CriteriaBuilder;
import jakarta.persistence.criteria.Root;
import jakarta.persistence.criteria.*;
+import jakarta.servlet.http.HttpServletResponse;
import net.gepafin.tendermanagement.config.Translator;
import net.gepafin.tendermanagement.constants.GepafinConstant;
import net.gepafin.tendermanagement.entities.*;
@@ -28,15 +33,14 @@ import net.gepafin.tendermanagement.service.FormService;
import net.gepafin.tendermanagement.service.HubService;
import net.gepafin.tendermanagement.service.SystemEmailTemplatesService;
import net.gepafin.tendermanagement.service.UserService;
-import net.gepafin.tendermanagement.util.DateTimeUtil;
-import net.gepafin.tendermanagement.util.FieldValidator;
-import net.gepafin.tendermanagement.util.LoggingUtil;
-import net.gepafin.tendermanagement.util.Utils;
-import net.gepafin.tendermanagement.util.Validator;
+import net.gepafin.tendermanagement.util.*;
import net.gepafin.tendermanagement.web.rest.api.errors.CustomValidationException;
import net.gepafin.tendermanagement.web.rest.api.errors.ResourceNotFoundException;
import net.gepafin.tendermanagement.web.rest.api.errors.Status;
+import org.apache.commons.csv.CSVFormat;
+import org.apache.commons.csv.CSVPrinter;
+import org.apache.commons.lang3.StringUtils;
import org.h2.util.IOUtils;
import org.json.JSONObject;
import org.slf4j.Logger;
@@ -54,17 +58,17 @@ import jakarta.servlet.http.HttpServletRequest;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.io.OutputStreamWriter;
+import java.lang.reflect.Method;
import java.math.BigDecimal;
+
import java.sql.Timestamp;
import java.text.MessageFormat;
-import java.text.NumberFormat;
-import java.text.ParseException;
+import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
-import java.time.LocalTime;
import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
-import java.time.format.DateTimeParseException;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -74,7 +78,6 @@ import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import static org.apache.commons.lang3.StringUtils.isEmpty;
-import static org.hibernate.validator.internal.engine.messageinterpolation.el.RootResolver.FORMATTER;
@Component
public class ApplicationDao {
@@ -138,6 +141,9 @@ public class ApplicationDao {
@Value("${call.id}")
private String callId;
+ @Value("${sviluppumbriaUuid}")
+ private String sviluppumbriaUuid;
+
@Autowired
private AmazonS3Service amazonS3Service;
@@ -201,15 +207,28 @@ public class ApplicationDao {
@Autowired
private ApplicationViewRepository applicationViewRepository;
+ @Autowired
+ private ApplicationFormViewRepository applicationFormViewRepository;
+
+ @Autowired
+ private FormRepository formRepository;
+
+ @Autowired
+ private ApplicationEvaluationDao applicationEvaluationDao;
+
+ public final Random random = new Random();
public ApplicationResponseBean createApplication(HttpServletRequest request, ApplicationRequestBean applicationRequestBean, Long formId, Long applicationId) {
+ log.info("Starting createApplication: formId={}, applicationId={}", formId, applicationId);
FormEntity formEntity = formService.validateForm(formId);
// callService.validatePublishedCall(formEntity.getCall().getId());
validateFormFields(applicationRequestBean,formEntity);
ApplicationEntity applicationEntity = validateApplication(applicationId);
checkCallEndDate(applicationEntity.getCall());
validator.validateUserWithCompany(request, applicationEntity.getCompanyId());
+ log.info("Validated user-company association for company ID: {}", applicationEntity.getCompanyId());
if(Boolean.FALSE.equals(applicationEntity.getStatus().equals(ApplicationStatusTypeEnum.DRAFT.getValue()))) {
+ log.warn("Application ID {} is not in DRAFT status", applicationId);
throw new CustomValidationException(Status.BAD_REQUEST,Translator.toLocale(GepafinConstant.APPLICATION_NOT_IN_DRAFT_STATUS));
}
formService.validateFormField(applicationRequestBean.getFormFields(),applicationEntity,formEntity);
@@ -236,10 +255,12 @@ public class ApplicationDao {
}
public ApplicationFormEntity createApplicationFormEntity(ApplicationEntity application, FormEntity formEntity) {
+ log.info("Creating ApplicationFormEntity for applicationId: {}, formId: {}", application.getId(), formEntity.getId());
ApplicationFormEntity applicationFormEntity = new ApplicationFormEntity();
applicationFormEntity.setApplication(application);
applicationFormEntity.setForm(formEntity);
applicationFormEntity = saveApplicationFormEntity(applicationFormEntity);
+ log.info("Created ApplicationFormEntity with id: {}", applicationFormEntity.getId());
return applicationFormEntity;
}
@@ -291,6 +312,7 @@ public class ApplicationDao {
List documentResponseBeans = new ArrayList<>();
if (fileUploadContent.isPresent()) {
String documentId = applicationFormFieldEntity.getFieldValue();
+ log.debug("Field is file upload/select type. Document IDs: {}", documentId);
if (documentId != null && !documentId.isEmpty()) {
documentResponseBeans = Arrays.stream(documentId.split(","))
.map(String::trim)
@@ -298,6 +320,7 @@ public class ApplicationDao {
.map(docId -> {
DocumentEntity documentEntity = documentService.validateDocument(docId);
if (Boolean.FALSE.equals(DocumentSourceTypeEnum.APPLICATION.getValue().equals(documentEntity.getSource()))) {
+ log.warn("Document {} source type invalid: {}", docId, documentEntity.getSource());
throw new CustomValidationException(Status.NOT_FOUND,Translator.toLocale(GepafinConstant.DOCUMENT_NOT_FOUND));
}
return documentEntity;
@@ -323,6 +346,7 @@ public class ApplicationDao {
ApplicationEntity applicationEntity= validateApplication(id);
if (Boolean.FALSE.equals(ApplicationStatusTypeEnum.DRAFT.getValue().equals(applicationEntity.getStatus()))) {
+ log.warn("Application with ID: {} is not in DRAFT status, cannot delete. Current status: {}", id, applicationEntity.getStatus());
throw new CustomValidationException(
Status.VALIDATION_ERROR,
Translator.toLocale(GepafinConstant.APPLICATION_NOT_IN_DRAFT_STATUS)
@@ -333,6 +357,7 @@ public class ApplicationDao {
validator.validateUserWithCompany(request, applicationEntity.getCompanyId());
applicationEntity.setIsDeleted(true);
applicationEntity = applicationRepository.save(applicationEntity);
+ log.info("Marked application as deleted and saved for ID: {}", id);
/** This code is responsible for adding a version history log for the "Delete application" operation. **/
loggingUtil.addVersionHistory(
@@ -420,6 +445,7 @@ public class ApplicationDao {
}
private ApplicationResponse getApplicationResponse(ApplicationEntity applicationEntity) {
+ log.info("Generating ApplicationResponse for application ID: {}", applicationEntity.getId());
ApplicationResponse responseBean = new ApplicationResponse();
List flowEdgesList = flowEdgesRepository.findByCallId(applicationEntity.getCall().getId());
Long totalFormSteps = flowFormDao.calculateTotalSteps(flowEdgesList);
@@ -460,9 +486,13 @@ public class ApplicationDao {
}
public ApplicationEntity validateApplication(Long id) {
+ log.info("Validating existence of Application with ID: {}", id);
ApplicationEntity applicationEntity = applicationRepository.findById(id)
- .orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND,
- Translator.toLocale(GepafinConstant.APPLICATION_NOT_FOUND_MSG)));
+ .orElseThrow(() -> {
+ log.warn("Application not found for ID: {}", id);
+ return new ResourceNotFoundException(Status.NOT_FOUND,
+ Translator.toLocale(GepafinConstant.APPLICATION_NOT_FOUND_MSG));
+ });
return applicationEntity;
}
@@ -486,10 +516,12 @@ public class ApplicationDao {
}
private ApplicationFormEntity getApplicationFormOrCreate(FormEntity formEntity, ApplicationEntity applicationEntity) {
+ log.info("Fetching ApplicationForm for Application ID: {} and Form ID: {}", applicationEntity.getId(), formEntity.getId());
ApplicationFormEntity applicationFormEntity = applicationFormRepository.findByApplicationIdAndFormId(applicationEntity.getId(), formEntity.getId());
ApplicationFormEntity oldApplicationFormEntity = Utils.getClonedEntityForData(applicationFormEntity);
if (applicationFormEntity == null) {
+ log.info("No existing ApplicationForm found. Creating new ApplicationForm for Application ID: {}, Form ID: {}", applicationEntity.getId(), formEntity.getId());
applicationFormEntity = createApplicationFormEntity(applicationEntity, formEntity);
/** This code is responsible for adding a version history log for the "Create application form" operation. **/
@@ -515,6 +547,8 @@ public class ApplicationDao {
public ApplicationFormFieldEntity createOrUpdateApplicationFormField(ApplicationFormFieldRequestBean applicationFormFieldRequestBean,
ApplicationFormEntity applicationFormEntity, List applicationFormFieldEntities, FormEntity formEntity,FieldValidator fieldValidator) {
+ log.info("Starting createOrUpdateApplicationFormField for ApplicationForm ID: {}", applicationFormEntity.getId());
+
ApplicationFormFieldEntity applicationFormFieldEntity = new ApplicationFormFieldEntity();
List newDocumentIds = validateFileUploadDocuments(applicationFormFieldRequestBean, formEntity);
@@ -534,7 +568,9 @@ public class ApplicationDao {
try {
BigDecimal amountRequested = new BigDecimal(fieldValue.toString());
applicationFormEntity.getApplication().setAmountRequested(amountRequested);
+ log.info("Set amountRequested to {} for Application ID: {}", amountRequested, applicationFormEntity.getApplication().getId());
} catch (NumberFormatException e) {
+ log.error("Invalid number format for requested amount: {}", fieldValue, e);
throw new IllegalArgumentException("Field value is not a valid number: " + fieldValue, e);
}
}
@@ -675,6 +711,8 @@ public class ApplicationDao {
List documentIds=null;
// List contentResponseBeans=Utils.convertJsonStringToList(formEntity.getContent(),ContentResponseBean.class);
List contentResponseBeans=formDao.convertFormEntityToFormResponseBean(formEntity).getContent();
+ log.debug("Validating file upload documents for field ID: {} in form ID: {}", applicationFormFieldRequestBean.getFieldId(), formEntity.getId());
+
for (ContentResponseBean contentResponseBean:contentResponseBeans){
if(Boolean.TRUE.equals(contentResponseBean.getName().equals("fileupload")) || Boolean.TRUE.equals(contentResponseBean.getName().equals("fileselect"))) {
if (contentResponseBean.getId().equals(applicationFormFieldRequestBean.getFieldId())) {
@@ -684,6 +722,7 @@ public class ApplicationDao {
String documentId = (String) fieldValueObject;
// Now you can use documentId as needed
documentIds = validateDocumentIds(documentId);
+ log.info("Validated document IDs: {}", documentIds);
}
}
}
@@ -693,6 +732,7 @@ public class ApplicationDao {
public List validateDocumentIds(String documentId) {
if (documentId != null && !documentId.isEmpty()) {
+ log.info("Validating document IDs: {}", documentId);
return Arrays.stream(documentId.split(","))
.map(Long::parseLong)
.peek(docId -> documentService.validateDocument(docId))
@@ -745,6 +785,7 @@ public class ApplicationDao {
}
public ApplicationGetResponseBean getApplicationByFormId(HttpServletRequest request, Long applicationId, Long formId) {
+ log.info("Received request to get application by formId. ApplicationId: {}, FormId: {}", applicationId, formId);
List formApplicationResponses = new ArrayList<>();
List formEntities = new ArrayList<>();
UserEntity userEntity = validator.validateUser(request);
@@ -895,6 +936,7 @@ public class ApplicationDao {
public ApplicationResponse createApplicationByCallId(CompanyEntity companyEntity,
ApplicationRequest applicationRequest, Long callId, UserEntity userEntity) {
+ log.info("Start creating application for CallId: {}, UserId: {}, CompanyId: {}", callId, userEntity.getId(), companyEntity.getId());
CallEntity call = callService.validateCall(callId);
UserWithCompanyEntity userWithCompanyEntity=companyService.getUserWithCompany(userEntity.getId(),companyEntity.getId());
checkCallEndDate(call);
@@ -918,39 +960,63 @@ public class ApplicationDao {
public void checkIfApplicationExists(CallEntity call, UserWithCompanyEntity userWithCompanyEntity, UserEntity userEntity){
+ log.info("Checking existing applications for UserId: {}, UserWithCompanyId: {}, CallId: {}",
+ userEntity.getId(), userWithCompanyEntity.getId(), call.getId());
List applications = applicationRepository.findByUserIdAndUserWithCompany_IdAndCall_IdAndIsDeletedFalseAndStatusNot(
userEntity.getId(), userWithCompanyEntity.getId(), call.getId(), ApplicationStatusTypeEnum.REJECTED.name()
);
if (!applications.isEmpty()) {
+ log.warn("Application already exists for UserId: {}, UserWithCompanyId: {}, CallId: {}. Applications found: {}",
+ userEntity.getId(), userWithCompanyEntity.getId(), call.getId(), applications.size());
throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.APPLICATION_ALREADY_EXISTS));
}
}
+ public String generateRandomFiveDigitNumber() {
+ int number = 10000 + random.nextInt(90000); // Generates a number from 10000 to 99999
+ return String.valueOf(number);
+ }
public ApplicationResponse updateApplicationStatus(HttpServletRequest request, Long applicationId, ApplicationStatusTypeEnum status) {
log.info("Updating status for Application id : " + applicationId);
ApplicationEntity applicationEntity = validateApplication(applicationId);
- checkCallEndDate(applicationEntity.getCall());
+
log.info("Call end date verified successfully | callId: {}", applicationEntity.getCall().getId());
//cloned entity for old application data
ApplicationEntity oldApplicationEntity = Utils.getClonedEntityForData(applicationEntity);
-
+ HubEntity hub=hubService.valdateHub(applicationEntity.getHubId());
UserEntity userEntity = userService.validateUser(applicationEntity.getUserId());
validator.validateUserWithCompany(request, applicationEntity.getCompanyId());
if (ApplicationStatusTypeEnum.SUBMIT.getValue().equals(applicationEntity.getStatus())) {
+ log.warn("Attempt to change status after submission denied | applicationId: {}", applicationId);
throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.APPLICATION_SUBMITTED_CANNOT_CHANGE));
}
if (Boolean.TRUE.equals(applicationEntity.getStatus().equals(status.getValue()))) {
+ log.warn("Requested status is the same as current status | applicationId: {}, status: {}", applicationId, status);
throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.APPLICATION_ALREADY_IN_PREVIOUS_STATUS));
}
+
+ if (status.equals(ApplicationStatusTypeEnum.APPOINTMENT) && Boolean.TRUE.equals(applicationEntity.getStatus().equals(ApplicationStatusTypeEnum.NDG.getValue()))){
+ String appointmentId = generateRandomFiveDigitNumber();
+ applicationEntity.setAppointmentId(appointmentId);
+ applicationEntity.setStatus(ApplicationStatusTypeEnum.APPOINTMENT.getValue());
+ }
+
if (status.equals(ApplicationStatusTypeEnum.SUBMIT) && Boolean.TRUE.equals(applicationEntity.getStatus().equals(ApplicationStatusTypeEnum.READY.getValue()))) {
+ CompanyEntity company=companyService.validateCompany(applicationEntity.getCompanyId());
+
// callService.validatePublishedCall(applicationEntity.getCall().getId(), userEntity.getHub().getId());
+ checkCallEndDate(applicationEntity.getCall());
Long protocolNumber = protocolDao.getProtocolNumber(userEntity.getHub());
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);
+ }
applicationEntity.setStatus(ApplicationStatusTypeEnum.SUBMIT.getValue());
applicationEntity.setSubmissionDate(protocolEntity.getCreatedDate());
applicationEntity = applicationRepository.save(applicationEntity);
@@ -961,16 +1027,18 @@ public class ApplicationDao {
loggingUtil.addVersionHistory(
VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplicationEntity).newData(applicationEntity).build());
- sendMailToUserAndCompany(userEntity, applicationEntity);
+ sendMailToUserAndCompany(userEntity, applicationEntity,company);
sendMailTodefaultSystemAndGepafin(userEntity, applicationEntity);
applicationEntity.setStatus(status.getValue());
log.info("Status updated to SUBMIT for applicationId: " + applicationId);
}
if (status.equals(ApplicationStatusTypeEnum.DRAFT) && Boolean.TRUE.equals(applicationEntity.getStatus().equals(ApplicationStatusTypeEnum.AWAITING.getValue()))) {
+ checkCallEndDate(applicationEntity.getCall());
applicationEntity.setStatus(status.getValue());
log.info("Status updated to DRAFT for applicationId: " + applicationId);
}
if (status.equals(ApplicationStatusTypeEnum.AWAITING) && Boolean.TRUE.equals(applicationEntity.getStatus().equals(ApplicationStatusTypeEnum.READY.getValue()))) {
+ checkCallEndDate(applicationEntity.getCall());
ApplicationSignedDocumentEntity applicationSignedDocument = applicationSignedDocumentRepository.findByApplicationIdAndStatus(applicationId,
ApplicationSignedDocumentStatusEnum.ACTIVE.getValue());
deleteSignedDocumentFromS3(applicationSignedDocument);
@@ -1072,9 +1140,9 @@ public class ApplicationDao {
}
}
- private void sendMailToUserAndCompany(UserEntity userEntity, ApplicationEntity applicationEntity) {
+ private void sendMailToUserAndCompany(UserEntity userEntity, ApplicationEntity applicationEntity,CompanyEntity company) {
+ log.info("Preparing to send submission email | applicationId: {}, userId: {}", applicationEntity.getId(), userEntity.getId());
CallEntity call =applicationEntity.getCall();
- CompanyEntity company=companyService.validateCompany(applicationEntity.getCompanyId());
UserWithCompanyEntity userWithCompany=companyService.getUserWithCompany(userEntity.getId(),company.getId());
ProtocolEntity protocol= applicationEntity.getProtocol();
HubEntity hub = hubService.valdateHub(applicationEntity.getHubId());
@@ -1102,7 +1170,7 @@ public class ApplicationDao {
if (userEntity.getBeneficiary() != null) {
emailLogRequest.setRecipientType(RecipientTypeEnum.BENEFICIARY);
email = userEntity.getBeneficiary().getEmail();
- emailLogRequest.setUserId(userEntity.getBeneficiary().getId());
+ emailLogRequest.setRecipientId(userEntity.getBeneficiary().getId());
}
emailNotificationDao.sendMail(hub.getId(), subject, body, List.of(email),emailLogRequest);
List recipientEmails = new ArrayList<>();
@@ -1151,24 +1219,6 @@ public class ApplicationDao {
EmailLogRequest emailLogRequest=emailLogDao.createEmailLogRequest(systemEmailTemplateResponse.getEmailScenario(),RecipientTypeEnum.PROPERTIES,null,userEntity.getEmail(),userEntity.getId(),applicationEntity.getId(),null,applicationEntity.getCall().getId());
-// mailUtil.sendByMailGun(subject, body, List.of(defaultSystemReceiverEmail), null);
-// mailUtil.sendByMailGun(subject, body, List.of(gepafinEmail), null);
-// mailUtil.sendByMailGun(subject, body, List.of(rinaldoEmail), null);
-// if(Boolean.TRUE.equals(hub.getUniqueUuid().equals(defaultHubUuid))) {
-// if (validator.isProductionProfileActivated()) {
-// emailLogRequest.setRecipientEmails(carloEmail);
-//// mailUtil.sendByMailGun(subject, body, List.of(carloEmail), null);
-// emailNotificationDao.sendMail(hub.getId(), subject, body, List.of(carloEmail),emailLogRequest);
-// }
-// List listDefaultSystemReceiverEmail = Arrays.stream(defaultSystemReceiverEmail.split(","))
-// .map(String::trim)
-// .filter(email -> !email.isEmpty())
-// .toList();
-//
-// emailLogRequest.setRecipientEmails(defaultSystemReceiverEmail);
-// emailNotificationDao.sendMail(hub.getId(), subject, body, listDefaultSystemReceiverEmail, emailLogRequest);
-// }
-
List hubEmails = Arrays.stream(hub.getEmail().split(","))
.map(String::trim)
.filter(email -> !email.isEmpty())
@@ -1181,6 +1231,7 @@ public class ApplicationDao {
}
public ApplicationSignedDocumentResponse uploadSignedDocument(HttpServletRequest request, Long applicationId,
MultipartFile file) {
+ log.info("Received request to upload signed document | applicationId: {}, fileName: {}", applicationId, file.getOriginalFilename());
ApplicationEntity applicationEntity = validateApplication(applicationId);
checkCallEndDate(applicationEntity.getCall());
//cloned entity for old data
@@ -1193,14 +1244,23 @@ public class ApplicationDao {
ApplicationSignedDocumentEntity oldApplicationSingedDocumentData = Utils.getClonedEntityForData(applicationSignedDocument);
if (applicationSignedDocument != null) {
+ log.info("Existing active signed document found and will be deleted | applicationId: {}, fileName: {}", applicationId, applicationSignedDocument.getFileName());
deleteSignedDocumentFromS3(applicationSignedDocument);
}
+ String hash ="";
+ try {
+ hash = FileHashUtil.calculateSHA256(file.getInputStream());
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
UploadFileOnAmazonS3Response uploadFileOnAmazonS3 = uploadFileOnAmazonS3ForUserSignedDocument(file, applicationEntity.getCall().getId(), applicationId);
+ log.info("File uploaded to S3 successfully | applicationId: {}", applicationId);
applicationSignedDocument = new ApplicationSignedDocumentEntity();
applicationSignedDocument.setApplication(applicationEntity);
applicationSignedDocument.setFileName(uploadFileOnAmazonS3.getFileName());
applicationSignedDocument.setFilePath(uploadFileOnAmazonS3.getFilePath());
applicationSignedDocument.setStatus(ApplicationSignedDocumentStatusEnum.ACTIVE.getValue());
+ applicationSignedDocument.setFileHash(hash);
applicationSignedDocument = applicationSignedDocumentRepository.save(applicationSignedDocument);
/** This code is responsible for adding a version history log for the "assign application document" operation. **/
@@ -1209,6 +1269,8 @@ public class ApplicationDao {
applicationEntity.setStatus(ApplicationStatusTypeEnum.READY.getValue());
applicationEntity = applicationRepository.save(applicationEntity);
+ log.info("Application status updated to READY | applicationId: {}", applicationEntity.getId());
+
/** This code is responsible for adding a version history log for the "Create Call" operation. **/
loggingUtil.addVersionHistory(
@@ -1217,16 +1279,22 @@ public class ApplicationDao {
return convertApplicationSignedDocumentToApplicationSignedDocumentResponse(applicationSignedDocument);
}
public void deleteSignedDocumentFromS3(ApplicationSignedDocumentEntity applicationSignedDocumentEntity){
+ log.info("Starting soft delete of signed document | applicationSignedDocumentId: {}, fileName: {}",
+ applicationSignedDocumentEntity.getId(), applicationSignedDocumentEntity.getFileName());
ApplicationSignedDocumentEntity oldApplicationSignedDocument = Utils.getClonedEntityForData(applicationSignedDocumentEntity);
String oldS3Path = applicationSignedDocumentEntity.getFilePath();
+ log.debug("Old S3 path: {} ", oldS3Path);
String newS3Path = s3ConfigBean.generateDocumentPathForOther(DocOtherSourceTypeEnum.DELETED_USER_SIGNED_DOCUMENT,applicationSignedDocumentEntity.getApplication().getCall().getId(),applicationSignedDocumentEntity.getApplication().getId(),0L);
+ log.debug("Generated new S3 path for deleted document: {}", newS3Path);
UploadFileOnAmazonS3Response response = amazonS3Service.moveFile(applicationSignedDocumentEntity.getFileName(), oldS3Path, newS3Path);
+ log.info("Moved file in S3 from {} to {} | fileName: {}", oldS3Path, newS3Path, response.getFileName());
applicationSignedDocumentEntity.setStatus(ApplicationSignedDocumentStatusEnum.INACTIVE.getValue());
applicationSignedDocumentEntity.setFileName(response.getFileName());
applicationSignedDocumentEntity.setFilePath(response.getFilePath());
applicationSignedDocumentRepository.save(applicationSignedDocumentEntity);
+ log.info("Updated signed document entity status to INACTIVE and saved | applicationSignedDocumentId: {}", applicationSignedDocumentEntity.getId());
loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.SOFT_DELETE).oldData(oldApplicationSignedDocument).newData(applicationSignedDocumentEntity).build());
}
@@ -1245,6 +1313,7 @@ public class ApplicationDao {
log.info("S3 Path {}", s3Path);
return amazonS3Service.uploadFileOnAmazonS3(s3Path, file);
} catch (Exception e) {
+ log.error("Failed to upload user signed document | callId: {}, applicationId: {}, error: {}", callId, applicationId, e.getMessage(), e);
throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.UPLOAD_ERROR_S3));
}
}
@@ -1252,6 +1321,7 @@ public class ApplicationDao {
try {
return s3ConfigBean.generateDocumentPathForOther(DocOtherSourceTypeEnum.USER_SIGNED_DOCUMENT, callId, applicationId,0L);
} catch (IllegalArgumentException e) {
+ log.error("Failed to generate S3 path for delegation | callId: {}, applicationId: {}, error: {}", callId, applicationId, e.getMessage(), e);
throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.S3_PATH_GENERATION_ERROR_MSG));
}
}
@@ -1266,6 +1336,7 @@ public class ApplicationDao {
.setStatus(ApplicationSignedDocumentStatusEnum.valueOf(applicationSignedDocument.getStatus()));
applicationSignedDocumentResponse.setCreatedDate(applicationSignedDocument.getCreatedDate());
applicationSignedDocumentResponse.setUpdatedDate(applicationSignedDocument.getUpdatedDate());
+ applicationSignedDocumentResponse.setFileHash(applicationSignedDocument.getFileHash());
return applicationSignedDocumentResponse;
}
@@ -1276,13 +1347,14 @@ public class ApplicationDao {
}
String filename = file.getOriginalFilename();
if (filename == null || !filename.endsWith(".p7m")) {
+ log.warn("Invalid file type detected | filename: {}", filename);
throw new CustomValidationException(Status.VALIDATION_ERROR,
Translator.toLocale(GepafinConstant.VALIDATION_ERROR_FILE_INVALIDTYPE));
}
}
public ApplicationSignedDocumentResponse getSignedDocument(HttpServletRequest request, Long applicationId) {
-
+ log.info("Fetching signed document for applicationId: {}", applicationId);
ApplicationEntity applicationEntity = validateApplication(applicationId);
// validator.validateUserWithCompany(request, applicationEntity.getCompanyId());
@@ -1296,6 +1368,7 @@ public class ApplicationDao {
ApplicationSignedDocumentEntity applicationSignedDocument = applicationSignedDocumentRepository
.findByApplicationIdAndStatus(applicationId, ApplicationSignedDocumentStatusEnum.ACTIVE.getValue());
if(applicationSignedDocument == null) {
+ log.warn("No active signed document found for applicationId: {}", applicationId);
throw new ResourceNotFoundException(Status.NOT_FOUND,
Translator.toLocale(GepafinConstant.APPLICATION_SIGNED_DOCUMENT_NOT_FOUND));
}
@@ -1303,6 +1376,7 @@ public class ApplicationDao {
}
public void deleteSignedDocument(HttpServletRequest request, Long applicationId) {
+ log.info("Initiating deletion of signed document for applicationId: {}", applicationId);
ApplicationEntity applicationEntity = validateApplication(applicationId);
validator.validateUserWithCompany(request, applicationEntity.getCompanyId());
@@ -1311,6 +1385,7 @@ public class ApplicationDao {
//cloned entity for old data
ApplicationSignedDocumentEntity oldApplicationSignedDocument = Utils.getClonedEntityForData(applicationSignedDocument);
if(applicationSignedDocument == null) {
+ log.warn("No active signed document found to delete for applicationId: {}", applicationId);
throw new ResourceNotFoundException(Status.NOT_FOUND,
Translator.toLocale(GepafinConstant.APPLICATION_SIGNED_DOCUMENT_NOT_FOUND));
}
@@ -1323,7 +1398,7 @@ public class ApplicationDao {
}
public ApplicationResponse validateApplication(HttpServletRequest request, Long applicationId) {
-
+ log.info("Starting application validation process | applicationId: {}", applicationId);
ApplicationEntity applicationEntity = validateApplication(applicationId);
ApplicationEntity oldApplicationEntity = Utils.getClonedEntityForData(applicationEntity);
checkCallEndDate(applicationEntity.getCall());
@@ -1331,15 +1406,18 @@ public class ApplicationDao {
UserEntity userEntity = userService.validateUser(applicationEntity.getUserId());
validator.validateUserWithCompany(request, applicationEntity.getCompanyId());
if (Boolean.FALSE.equals(ApplicationStatusTypeEnum.DRAFT.getValue().equals(applicationEntity.getStatus()))) {
+ log.warn("Application not in draft status | applicationId: {}, status: {}", applicationId, applicationEntity.getStatus());
throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.APPLICATION_NOT_IN_DRAFT_STATUS));
}
if (applicationEntity.getAmountRequested() == null || applicationEntity.getAmountRequested().compareTo(BigDecimal.ZERO) <= 0 ) {
+ log.warn("Invalid amount requested | amount: {}", applicationEntity.getAmountRequested());
throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.AMOUNT_REQUEST_SHOULD_GREATED_THEN_ZERO));
}
List flowEdgesList = flowEdgesRepository.findByCallId(applicationEntity.getCall().getId());
Long totalSteps = flowFormDao.calculateTotalSteps(flowEdgesList);
Integer completedSteps = flowFormDao.getCompletedSteps(applicationEntity, true);
if (totalSteps.intValue() != completedSteps) {
+ log.warn("Application incomplete | applicationId: {}", applicationId);
throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.APPLICATION_IS_INCOMPLETE_MSG));
}
@@ -1354,7 +1432,7 @@ public class ApplicationDao {
}
public byte[] downloadApplicationDocumentsAsZip(HttpServletRequest request, Long applicationId) {
-
+ log.info("Starting ZIP download process for applicationId: {}", applicationId);
ApplicationEntity applicationEntity = validateApplication(applicationId);
validateAssignedUser(request, applicationId);
Set documentIds = extractDocumentIdsFromApplicationForms(applicationId);
@@ -1364,13 +1442,14 @@ public class ApplicationDao {
List amendmentDocuments = fetchAmendmentDocuments(applicationId);
List evaluationDocuments = fetchEvaluationDocuments(applicationId);
if (documents.isEmpty() && signedDocument == null && amendmentDocuments.isEmpty() && evaluationDocuments.isEmpty()) {
+ log.warn("No documents found for applicationId: {}", applicationId);
throw new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.DOCUMENT_NOT_FOUND));
}
return createZipWithDocuments(applicationEntity, documents, signedDocument, amendmentDocuments, evaluationDocuments, applicationId);
}
private void validateAssignedUser(HttpServletRequest request, Long applicationId) {
-
+ log.info("Validating assigned user for applicationId: {}", applicationId);
AssignedApplicationsEntity assignedApplications = assignedApplicationsRepository.findByApplicationIdAndIsDeletedFalse(applicationId).orElse(null);
if (assignedApplications != null) {
validator.validatePreInstructor(request, assignedApplications.getUserId());
@@ -1378,7 +1457,7 @@ public class ApplicationDao {
}
private Set extractDocumentIdsFromApplicationForms(Long applicationId) {
-
+ log.info("Extracting document IDs from application forms | applicationId: {}", applicationId);
Set documentIds = new HashSet<>();
List applicationForms = applicationFormRepository.findByApplicationId(applicationId);
applicationForms.forEach(applicationForm -> {
@@ -1400,16 +1479,17 @@ public class ApplicationDao {
}
private List fetchAmendmentDocuments(Long applicationId) {
-
+ log.info("Fetching amendment documents for applicationId: {}", applicationId);
List amendmentRequests = applicationAmendmentRequestRepository.findByApplicationIdAndIsDeletedFalse(applicationId);
Set amendmentIds = amendmentRequests.stream().map(ApplicationAmendmentRequestEntity::getId).collect(Collectors.toSet());
return documentRepository.findBySourceIdInAndSourceAndIsDeletedFalse(amendmentIds, DocumentSourceTypeEnum.AMENDMENT.getValue());
}
private List fetchEvaluationDocuments(Long applicationId) {
-
+ log.info("Fetching evaluation documents for applicationId: {}", applicationId);
Optional evaluationEntity = applicationEvaluationRepository.findByApplicationIdAndIsDeletedFalse(applicationId);
if (evaluationEntity.isPresent()) {
Long evaluationId = evaluationEntity.get().getId();
+ log.debug("Found evaluation entity with id: {}", evaluationId);
return documentRepository.findBySourceIdInAndSourceAndIsDeletedFalse(Collections.singleton(evaluationId), DocumentSourceTypeEnum.EVALUATION.getValue());
}
return Collections.emptyList();
@@ -1423,12 +1503,14 @@ public class ApplicationDao {
return "unknown";
}
private void addDocumentToZip(ZipOutputStream zos, String s3Folder, String filePath, String fullPath) {
-
+ log.info("Attempting to add file to ZIP. S3 folder: {}, file path: {}", s3Folder, filePath);
try (InputStream fileInputStream = amazonS3Service.getFile(s3Folder, filePath)) {
zos.putNextEntry(new ZipEntry(fullPath));
IOUtils.copy(fileInputStream, zos);
zos.closeEntry();
} catch (IOException e) {
+ log.error("Failed to add file to ZIP. S3 folder: {}, file path: {}, error: {}",
+ s3Folder, filePath, e.getMessage(), e);
throw new RuntimeException("Error downloading or adding document to ZIP: " + fullPath, e);
}
}
@@ -1833,4 +1915,429 @@ public class ApplicationDao {
responseBean.setDateRejected(applicationView.getDateRejected());
return responseBean;
}
+
+ public List getApplicationFormData(Long callId) {
+ List applicationFormViews=new ArrayList<>();
+
+ applicationFormViews= applicationFormViewRepository.findByCallId(callId);
+
+ return applicationFormViews;
+ }
+
+ private List getStaticGetterMethods() {
+ List excluded = Arrays.asList(
+ GepafinConstant.GET_FIELD_TYPE,GepafinConstant.GET_APPLICATION_FORM_ID,GepafinConstant.GET_ID,GepafinConstant.GET_CLASS,GepafinConstant.GET_FORM_ID,GepafinConstant.GET_FIELD_ID,GepafinConstant.GET_FIELD_LABEL,GepafinConstant.GET_FIELD_VALUE,GepafinConstant.GET_REPORT_HEADER,GepafinConstant.GET_REPORT_ENABLE
+ );
+
+ Method applicationIdMethod = null;
+
+ List methods = new ArrayList<>();
+
+ for (Method m : ApplicationFormView.class.getMethods()) {
+ if (m.getName().equals(GepafinConstant.GET_APPLICATION_ID)) {
+ applicationIdMethod = m;
+ } else if (m.getName().startsWith(GepafinConstant.GET) && m.getParameterCount() == 0 && !excluded.contains(m.getName())) {
+ methods.add(m);
+ }
+ }
+
+ methods.sort(Comparator.comparing(Method::getName)); // Sort remaining
+
+ if (applicationIdMethod != null) {
+ methods.add(0, applicationIdMethod); // Add it to the beginning
+ }
+
+ return methods;
+
+ }
+
+ private String methodToHeader(Method method) {
+ String name = method.getName().substring(3); // strip "get"
+ return Arrays.stream(name.split("(?=[A-Z])"))
+ .map(String::toLowerCase)
+ .map(word -> Character.toUpperCase(word.charAt(0)) + word.substring(1))
+ .collect(Collectors.joining(" "));
+ }
+
+ private String invokeGetter(ApplicationFormView view, Method method) {
+ try {
+ Object value = method.invoke(view);
+ if (value == null) return "";
+
+ String stringValue;
+
+ if (value instanceof LocalDate) {
+ stringValue = ((LocalDate) value).format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
+ } else if (value instanceof LocalDateTime) {
+ stringValue = ((LocalDateTime) value).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
+ } else if (value instanceof Date) {
+ stringValue = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format((Date) value);
+ } else {
+ stringValue = value.toString();
+ }
+
+ // Wrap it in ="..." to make Excel treat it as a literal string
+ return "=\"" + stringValue.replace("\"", "\"\"") + "\"";
+
+ } catch (Exception e) {
+ return "";
+ }
+ }
+
+
+ public byte[] exportCsv(Long callId) {
+
+ List results = getApplicationFormData(callId);
+
+
+ Map appInfo = new HashMap<>();
+ Map> appFieldValues = new LinkedHashMap<>();
+ Set tableFieldIds = new HashSet<>();
+ Map fieldIdToLabel = new LinkedHashMap<>();
+
+ for (ApplicationFormView row : results) {
+ appInfo.putIfAbsent(row.getApplicationId(), row);
+ String label=row.getReportHeader();
+ if(Boolean.TRUE.equals(StringUtils.isEmpty(label))){
+ label=row.getFieldLabel();
+ }
+ fieldIdToLabel.putIfAbsent(row.getFieldId(), label);
+
+ if (GepafinConstant.TABLE.equalsIgnoreCase(row.getFieldType())) {
+ tableFieldIds.add(row.getFieldId());
+ continue;
+ }
+
+ String value = Optional.ofNullable(row.getFieldValue())
+ .map(v -> v.startsWith("\"") && v.endsWith("\"") ? v.substring(1, v.length() - 1) : v)
+ .orElse("");
+
+ appFieldValues
+ .computeIfAbsent(row.getApplicationId(), k -> new LinkedHashMap<>())
+ .merge(row.getFieldId(), value, (v1, v2) -> v1.equals(v2) ? v1 : String.join(", ", v1, v2));
+ }
+
+ Map> tableHeadersByFieldId = new LinkedHashMap<>();
+ Map> tableDataByApp = new HashMap<>();
+ prepareTableFieldData(results, tableFieldIds, tableHeadersByFieldId, tableDataByApp);
+
+ // Final header construction
+ List staticMethods = getStaticGetterMethods();
+ List staticHeaders = staticMethods.stream().map(this::methodToHeader).toList();
+
+ List dynamicHeaders = new ArrayList<>();
+ for (String fieldId : fieldIdToLabel.keySet()) {
+ if (tableHeadersByFieldId.containsKey(fieldId)) {
+ dynamicHeaders.addAll(tableHeadersByFieldId.get(fieldId));
+ } else {
+ dynamicHeaders.add(fieldIdToLabel.get(fieldId));
+ }
+ }
+
+ List allHeaders = new ArrayList<>(staticHeaders);
+ allHeaders.addAll(dynamicHeaders);
+
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ try (CSVPrinter printer = new CSVPrinter(new OutputStreamWriter(out), CSVFormat.DEFAULT.withHeader(allHeaders.toArray(new String[0])))) {
+ for (Long appId : appFieldValues.keySet()) {
+ ApplicationFormView appRow = appInfo.get(appId);
+ Map flatFieldVals = appFieldValues.get(appId);
+ Map tableVals = tableDataByApp.getOrDefault(appId, Collections.emptyMap());
+
+ List row = new ArrayList<>();
+ for (Method method : staticMethods) {
+ row.add(invokeGetter(appRow, method));
+ }
+
+ for (String fieldId : fieldIdToLabel.keySet()) {
+ if (tableHeadersByFieldId.containsKey(fieldId)) {
+ for (String header : tableHeadersByFieldId.get(fieldId)) {
+ row.add(tableVals.getOrDefault(header, ""));
+ }
+ } else {
+ row.add(flatFieldVals.getOrDefault(fieldId, ""));
+ }
+ }
+
+ printer.printRecord(row);
+ }
+
+ } catch (IOException e) {
+ throw new RuntimeException("CSV generation failed", e);
+ }
+
+ return out.toByteArray();
+ }
+ private Map extractTableData(String fieldType,
+ ContentResponseBean content, String fieldValue) {
+
+ if (content == null) return Map.of();
+
+ Map result = new LinkedHashMap<>();
+
+ List