package net.gepafin.tendermanagement.dao; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import jakarta.persistence.criteria.Join; import jakarta.persistence.criteria.Predicate; import jakarta.servlet.http.HttpServletRequest; import net.gepafin.tendermanagement.config.Translator; import net.gepafin.tendermanagement.constants.GepafinConstant; import net.gepafin.tendermanagement.entities.*; import net.gepafin.tendermanagement.enums.*; import net.gepafin.tendermanagement.model.request.ApplicationAmendmentRequest; import net.gepafin.tendermanagement.model.request.ApplicationAmendmentRequestBean; import net.gepafin.tendermanagement.model.request.ApplicationFormFieldRequestBean; import net.gepafin.tendermanagement.model.request.CloseAmendmentRequest; import net.gepafin.tendermanagement.model.response.*; import net.gepafin.tendermanagement.repositories.*; import net.gepafin.tendermanagement.service.*; import net.gepafin.tendermanagement.util.DateTimeUtil; import net.gepafin.tendermanagement.util.Validator; import net.gepafin.tendermanagement.entities.SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum; import net.gepafin.tendermanagement.util.Utils; import net.gepafin.tendermanagement.web.rest.api.errors.CustomValidationException; import net.gepafin.tendermanagement.web.rest.api.errors.ResourceNotFoundException; import net.gepafin.tendermanagement.web.rest.api.errors.Status; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.data.jpa.domain.Specification; import org.springframework.stereotype.Component; import java.time.temporal.ChronoUnit; import java.time.LocalDateTime; import java.util.*; import java.util.stream.Collectors; import static net.gepafin.tendermanagement.util.Utils.log; import static net.gepafin.tendermanagement.util.Utils.setIfUpdated; @Component public class ApplicationAmendmentRequestDao { @Value("${application.amendment.expiration.days}") private long expirationDays; @Autowired private ApplicationService applicationService; @Autowired private UserService userService; @Autowired private DocumentService documentService; @Autowired private ApplicationFormRepository applicationFormRepository; @Autowired private ApplicationAmendmentRequestRepository applicationAmendmentRequestRepository; @Autowired private ApplicationFormFieldRepository applicationFormFieldRepository; @Autowired private EmailNotificationDao emailNotificationDao; @Autowired private ApplicationEvaluationService applicationEvaluationService; @Autowired private ProtocolDao protocolDao; @Autowired private AssignedApplicationsService assignedApplicationsService; @Autowired private ApplicationEvaluationRepository applicationEvaluationRepository; @Autowired private ApplicationRepository applicationRepository; @Autowired private AssignedApplicationsRepository assignedApplicationsRepository; @Autowired private SystemEmailTemplatesService systemEmailTemplatesService; @Autowired private CallDao callDao; @Autowired private DocumentRepository documentRepository; @Autowired private HubService hubService; // @Autowired // private MailUtil mailUtil; @Autowired private Validator validator; public ApplicationAmendmentRequestResponse getApplicationDataForAmendment(Long applicationEvaluationId) { log.info("Fetching the application data for the Amendment process {}", applicationEvaluationId); ApplicationEvaluationEntity applicationEvaluationEntity = applicationEvaluationService.validateApplicationEvaluation(applicationEvaluationId); Long applicationId = applicationEvaluationEntity.getApplicationId(); ApplicationEntity application = applicationService.validateApplication(applicationId); // Set common application-level details String callName = application.getCall().getName(); Long protocolNumber = (application.getProtocol() != null && application.getProtocol().getProtocolNumber() != null) ? application.getProtocol().getProtocolNumber() : null; UserEntity userEntity = userService.validateUser(application.getUserId()); String firstName = userEntity.getBeneficiary() != null ? userEntity.getBeneficiary().getFirstName() : ""; String lastName = userEntity.getBeneficiary() != null ? userEntity.getBeneficiary().getLastName() : ""; String beneficiaryName = (!firstName.isBlank() ? firstName : "") + (!lastName.isBlank() ? " " + lastName : ""); beneficiaryName = beneficiaryName.isBlank() ? "" : beneficiaryName; ApplicationAmendmentRequestResponse response = new ApplicationAmendmentRequestResponse(); response.setId(applicationEvaluationId); response.setProtocolNumber(protocolNumber); response.setCallName(callName); response.setBeneficiaryName(beneficiaryName); response.setApplicationId(applicationId); response.setApplicationEvaluationId(applicationEvaluationId); List forms = applicationFormRepository.findByApplicationId(applicationId); List allFormFields = new ArrayList<>(); for (ApplicationFormEntity form : forms) { String content = form.getForm().getContent(); List> result = filterByName(content, "fileupload"); allFormFields.addAll(getIdAndLabelFromResult(result)); } response.setFormFields(allFormFields); return response; } public List getIdAndLabelFromResult(List> result) { List formFieldResponses = new ArrayList<>(); for (Map item : result) { AmendmentFormFieldResponse formFieldResponse = new AmendmentFormFieldResponse(); formFieldResponse.setFieldId((String) item.get("id")); // Extract "label" value from the "settings" array List> settings = (List>) item.get("settings"); String label = settings.stream() .filter(setting -> "label".equals(setting.get("name"))) .map(setting -> (String) setting.get("value")) .findFirst() .orElse(""); // Default to empty string if not found if (label == null || label.trim().isEmpty()) { continue; } formFieldResponse.setLabel(label); // Set the label as fieldValue formFieldResponses.add(formFieldResponse); } return formFieldResponses; } public static List> filterByName(String content, String target) { ObjectMapper objectMapper = new ObjectMapper(); List> filteredList = new ArrayList<>(); try { List> dataList = objectMapper.readValue( content, new TypeReference>>() {}); for (Map data : dataList) { if (target.equals(data.get("name"))) { filteredList.add(data); } } } catch (Exception e) { e.printStackTrace(); } return filteredList; } public ApplicationAmendmentRequestResponse createApplicationAmendmentRequest(Long applicationEvaluationId, ApplicationAmendmentRequest applicationAmendmentRequest){ log.info("Submiting application data for amendment Process with details: {}", applicationEvaluationId); ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity = createApplicationAmendmentRequestEntity(applicationAmendmentRequest, applicationEvaluationId); ApplicationAmendmentRequestResponse applicationAmendmentRequestResponse = convertEntityToResponse(applicationAmendmentRequestEntity); log.info("Application submitted successfully for amendment", applicationAmendmentRequestResponse); if(Boolean.TRUE.equals(applicationAmendmentRequestResponse.isSendEmail())){ emailNotificationDao.sendMailToNotifyBeneficiaryRegardingNewAmendment(applicationAmendmentRequestEntity); } return applicationAmendmentRequestResponse; } public ApplicationAmendmentRequestEntity createApplicationAmendmentRequestEntity(ApplicationAmendmentRequest applicationAmendmentRequest,Long applicationEvaluationId){ ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity = new ApplicationAmendmentRequestEntity(); applicationAmendmentRequestEntity.setNote(applicationAmendmentRequest.getNote()); applicationAmendmentRequestEntity.setResponseDays(applicationAmendmentRequest.getResponseDays()); applicationAmendmentRequestEntity.setIsEmail(applicationAmendmentRequest.getIsSendEmail()); applicationAmendmentRequestEntity.setIsNotification(applicationAmendmentRequest.getIsSendNotification()); applicationAmendmentRequestEntity.setStartDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); applicationAmendmentRequestEntity.setStatus(ApplicationAmendmentRequestEnum.AWAITING.getValue()); ApplicationEvaluationEntity applicationEvaluationEntity = applicationEvaluationService.validateApplicationEvaluation(applicationEvaluationId); applicationAmendmentRequestEntity.setApplicationEvaluationEntity(applicationEvaluationEntity); Long applicationId = applicationEvaluationEntity.getApplicationId(); Long assignedApplicationId = applicationEvaluationEntity.getAssignedApplicationsEntity().getId(); applicationAmendmentRequestEntity.setApplicationId(applicationId); if (applicationAmendmentRequest.getFormFields() != null) { String fieldIdsString = applicationAmendmentRequest.getFormFields().stream() .filter(AmendmentFormFieldResponse::isSelected) .map(AmendmentFormFieldResponse::getFieldId) .collect(Collectors.joining(",")); applicationAmendmentRequestEntity.setFormFields(fieldIdsString); } UserEntity userEntity = userService.validateUser(applicationEvaluationEntity.getUserId()); Long protocolNumber = protocolDao.getProtocolNumber(userEntity.getHub()); ProtocolEntity protocolEntity = protocolDao.createProtocolEntity( applicationEvaluationEntity.getAssignedApplicationsEntity().getApplication(), protocolNumber, userEntity.getHub().getId()); applicationAmendmentRequestEntity.setProtocol(protocolEntity); ApplicationAmendmentRequestEntity applicationAmendment = saveApplicationAmendmentRequestEntity(applicationAmendmentRequestEntity); //Set Status applicationEvaluationEntity.setStatus(ApplicationEvaluationStatusTypeEnum.SOCCORSO.getValue()); applicationEvaluationRepository.save(applicationEvaluationEntity); ApplicationEntity applicationEntity = applicationService.validateApplication(applicationId); applicationEntity.setStatus(ApplicationStatusTypeEnum.SOCCORSO.getValue()); applicationRepository.save(applicationEntity); AssignedApplicationsEntity assignedApplicationsEntity = assignedApplicationsService.validateAssignedApplication(assignedApplicationId); assignedApplicationsEntity.setStatus(AssignedApplicationEnum.SOCCORSO.getValue()); assignedApplicationsRepository.save(assignedApplicationsEntity); return applicationAmendment; } public ApplicationAmendmentRequestEntity saveApplicationAmendmentRequestEntity(ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity){ ApplicationAmendmentRequestEntity applicationAmendmentRequest= applicationAmendmentRequestRepository.save(applicationAmendmentRequestEntity); return applicationAmendmentRequest; } public ApplicationAmendmentRequestResponse convertEntityToResponse(ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity){ ApplicationAmendmentRequestResponse applicationAmendmentRequestResponse = new ApplicationAmendmentRequestResponse(); applicationAmendmentRequestResponse.setId(applicationAmendmentRequestEntity.getId()); Long applicationId= applicationAmendmentRequestEntity.getApplicationId(); ApplicationEntity application = applicationService.validateApplication(applicationId); applicationAmendmentRequestResponse.setApplicationId(applicationId); applicationAmendmentRequestResponse.setCallEmail(application.getCall().getEmail()); applicationAmendmentRequestResponse.setApplicationEvaluationId(applicationAmendmentRequestEntity.getApplicationEvaluationEntity().getId()); applicationAmendmentRequestResponse.setNote(applicationAmendmentRequestEntity.getNote()); applicationAmendmentRequestResponse.setStatus(ApplicationAmendmentRequestEnum.valueOf(applicationAmendmentRequestEntity.getStatus())); applicationAmendmentRequestResponse.setResponseDays(applicationAmendmentRequestEntity.getResponseDays()); applicationAmendmentRequestResponse.setInternalNote(applicationAmendmentRequestEntity.getInternalNote()); LocalDateTime startDate = applicationAmendmentRequestEntity.getStartDate(); applicationAmendmentRequestResponse.setStartDate(startDate); LocalDateTime expirationDate = startDate.plus(expirationDays, ChronoUnit.DAYS); applicationAmendmentRequestResponse.setExpirationDate(expirationDate); applicationAmendmentRequestResponse.setSendEmail(applicationAmendmentRequestEntity.getIsEmail()); applicationAmendmentRequestResponse.setSendNotification(applicationAmendmentRequestEntity.getIsNotification()); String callName = application.getCall().getName(); Long protocolNumber = (applicationAmendmentRequestEntity.getProtocol() != null && applicationAmendmentRequestEntity.getProtocol().getProtocolNumber() != null) ? applicationAmendmentRequestEntity.getProtocol().getProtocolNumber() : null; UserEntity userEntity = userService.validateUser(application.getUserId()); String firstName = userEntity.getBeneficiary() != null ? userEntity.getBeneficiary().getFirstName() : ""; String lastName = userEntity.getBeneficiary() != null ? userEntity.getBeneficiary().getLastName() : ""; String beneficiaryName = (!firstName.isBlank() ? firstName : "") + (!lastName.isBlank() ? " " + lastName : ""); beneficiaryName = beneficiaryName.isBlank() ? "" : beneficiaryName; applicationAmendmentRequestResponse.setCallName(callName); applicationAmendmentRequestResponse.setProtocolNumber(protocolNumber); applicationAmendmentRequestResponse.setBeneficiaryName(beneficiaryName); String formFieldsString = applicationAmendmentRequestEntity.getFormFields(); List storedFieldIds = (formFieldsString != null) ? Arrays.asList(formFieldsString.split(",")) : Collections.emptyList(); List applicationForms = applicationFormRepository.findByApplicationId(application.getId()); List formFields = new ArrayList<>(); for (ApplicationFormEntity formEntity : applicationForms) { String content = formEntity.getForm().getContent(); List> result = filterByName(content, "fileupload"); List matchingFields = getIdAndLabelFromResult(result).stream() .filter(field -> storedFieldIds.contains(field.getFieldId())) .collect(Collectors.toList()); formFields.addAll(matchingFields); } applicationAmendmentRequestResponse.setFormFields(formFields); List formField = formFields.stream() .map(field -> { AmendmentFormFieldResponse responseField = new AmendmentFormFieldResponse(); responseField.setFieldId(field.getFieldId()); responseField.setLabel(field.getLabel()); responseField.setSelected(true); return responseField; }) .collect(Collectors.toList()); applicationAmendmentRequestResponse.setFormFields(formField); List formFieldEntities = applicationFormFieldRepository.findByApplicationFormIdIn( applicationForms.stream().map(ApplicationFormEntity::getId).collect(Collectors.toList()) ); List fileDetailResponses = new ArrayList<>(); for (AmendmentFormFieldResponse field : formFields) { for (ApplicationFormFieldEntity formFieldEntity : formFieldEntities) { if (formFieldEntity.getFieldId().equals(field.getFieldId()) && formFieldEntity.getFieldValue() != null) { ApplicationFormFieldResponseBean responseBean = new ApplicationFormFieldResponseBean(); responseBean.setFieldId(formFieldEntity.getFieldId()); String[] documentIds = formFieldEntity.getFieldValue().split(","); List documentResponseBeans = new ArrayList<>(); for (String docId : documentIds) { Long documentId = Long.valueOf(docId.trim()); documentRepository.findByIdAndNotDeleted(documentId).ifPresent(documentEntity -> { DocumentResponseBean docBean = new DocumentResponseBean(); docBean.setId(documentEntity.getId()); docBean.setName(documentEntity.getFileName()); docBean.setType(DocumentTypeEnum.valueOf(documentEntity.getType())); docBean.setSource(DocumentSourceTypeEnum.valueOf(documentEntity.getSource())); docBean.setSourceId(documentEntity.getSourceId()); docBean.setFilePath(documentEntity.getFilePath()); docBean.setCreatedDate(documentEntity.getCreatedDate()); docBean.setUpdatedDate(documentEntity.getUpdatedDate()); documentResponseBeans.add(docBean); }); } responseBean.setFieldValue(documentResponseBeans); fileDetailResponses.add(responseBean); } } } applicationAmendmentRequestResponse.setApplicationFormFields(fileDetailResponses); return applicationAmendmentRequestResponse; } public ApplicationAmendmentRequestEntity validateApplicationAmendmentRequest(Long id) { return applicationAmendmentRequestRepository.findByIdAndIsDeletedFalse(id) .orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.APPLICATION_AMENDMENT_NOT_FOUND_MSG))); } public void deleteById(Long id) { log.info("Deleting assigned application with ID: {}", id); ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity= validateApplicationAmendmentRequest(id); applicationAmendmentRequestEntity.setIsDeleted(true); saveApplicationAmendmentRequestEntity(applicationAmendmentRequestEntity); log.info(" Application amendment deleted with ID: {}", id); } public ApplicationAmendmentRequestResponse getApplicationAmendmentRequestById(Long id) { log.info("Fetching application amendment with ID: {}", id); ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity = validateApplicationAmendmentRequest(id); ApplicationAmendmentRequestResponse response = convertEntityToResponse(applicationAmendmentRequestEntity); log.info("Application Amendment fetched successfully by ID: {}", response); return response; } public List getAllApplicationAmendmentRequest(HttpServletRequest request,Long userId) { if(validator.checkIsPreInstructor() && userId == null) { throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.USER_ID_NOT_NULL_MSG)); } if(userId != null) { validator.validatePreInstructor(request, userId); } Specification spec = search(userId); List applicationAmendmentRequestEntities = applicationAmendmentRequestRepository.findAll(spec); return applicationAmendmentRequestEntities.stream() .map(this::convertEntityToResponse) .collect(Collectors.toList()); } private Specification search(Long userId) { return (root, query, builder) -> { Predicate predicate = builder.isFalse(root.get("isDeleted")); // Only non-deleted records if (userId != null) { Join evaluationJoin = root.join("applicationEvaluationEntity"); predicate = builder.and(predicate, builder.equal(evaluationJoin.get("userId"), userId)); } return predicate; // Return final predicate }; } public ApplicationAmendmentRequestResponse updateApplicationAmendment( Long id, ApplicationAmendmentRequestBean updateRequest) { log.info("Updating application amendement with ID: {}", id); ApplicationAmendmentRequestEntity existingApplicationAmendment = validateApplicationAmendmentRequest(id); setIfUpdated(existingApplicationAmendment::getNote, existingApplicationAmendment::setNote, updateRequest.getNote()); if (updateRequest.getApplicationFormFields() != null) { updateApplicationFormFields(existingApplicationAmendment, updateRequest.getApplicationFormFields()); } existingApplicationAmendment.setUpdatedDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); ApplicationAmendmentRequestEntity updatedApplicationAmendment = saveApplicationAmendmentRequestEntity(existingApplicationAmendment); ApplicationAmendmentRequestResponse response = convertEntityToResponse(updatedApplicationAmendment); log.info("Application Amendment updated successfully: {}", response); return response; } private void updateApplicationFormFields(ApplicationAmendmentRequestEntity applicationAmendment, ApplicationFormFieldRequestBean updatedFormField) { if (updatedFormField.getFieldValue() == null || "".equals(updatedFormField.getFieldValue().toString().trim())) { List applicationForms = applicationFormRepository.findByApplicationId(applicationAmendment.getApplicationId()); boolean fieldUpdated = false; for (ApplicationFormEntity applicationForm : applicationForms) { Optional formFieldEntityOptional = applicationFormFieldRepository .findByApplicationFormIdAndFieldId(applicationForm.getId(), updatedFormField.getFieldId()); if (formFieldEntityOptional.isPresent()) { ApplicationFormFieldEntity formEntity = formFieldEntityOptional.get(); formEntity.setFieldValue(null); // Set field value to null applicationFormFieldRepository.save(formEntity); log.info("Set field value to null for application ID {} and field ID {}", applicationAmendment.getApplicationId(), updatedFormField.getFieldId()); fieldUpdated = true; break; } } if (!fieldUpdated) { throw new CustomValidationException(Status.NOT_FOUND, "No ApplicationFormField found for application ID " + applicationAmendment.getApplicationId() + " and field ID " + updatedFormField.getFieldId()); } return; } List documentIds; if (updatedFormField.getFieldValue() instanceof String && updatedFormField.getFieldValue() != null) { documentIds = Arrays.asList(((String) updatedFormField.getFieldValue()).split(",")); } else { log.warn("Expected fieldValue as a comma-separated String but got: {}", updatedFormField.getFieldValue()); return; } List validDocumentIds = new ArrayList<>(); for (String documentId : documentIds) { try { DocumentEntity documentEntity = documentService.validateDocument(Long.parseLong(documentId.trim())); if (documentEntity != null) { validDocumentIds.add(documentId.trim()); } else { log.warn("Document with ID {} does not exist. Skipping this ID.", documentId); } } catch (NumberFormatException e) { log.error("Invalid document ID format: {}. Error: {}", documentId, e.getMessage()); } } if (!validDocumentIds.isEmpty()) { List applicationForms = applicationFormRepository.findByApplicationId(applicationAmendment.getApplicationId()); boolean fieldUpdated = false; for (ApplicationFormEntity applicationForm : applicationForms) { Optional formFieldEntityOptional = applicationFormFieldRepository .findByApplicationFormIdAndFieldId(applicationForm.getId(), updatedFormField.getFieldId()); if (formFieldEntityOptional.isPresent()) { ApplicationFormFieldEntity formEntity = formFieldEntityOptional.get(); formEntity.setFieldValue(String.join(",", validDocumentIds)); applicationFormFieldRepository.save(formEntity); log.info("Updated field value for application ID {} and field ID {} with document IDs {}", applicationAmendment.getApplicationId(), updatedFormField.getFieldId(), String.join(",", validDocumentIds)); fieldUpdated = true; break; } } if (!fieldUpdated) { throw new CustomValidationException(Status.NOT_FOUND,"No ApplicationFormField found for application ID {} and field ID {}. Skipping update."); } } else { log.warn("No valid document IDs found for update. Skipping field ID {}", updatedFormField.getFieldId()); } } public List getAllAmendmentRequestByBeneficiaryId(Long beneficiaryId) { UserEntity userEntity = userService.validateUser(beneficiaryId); List entities = applicationAmendmentRequestRepository.findByUserId(beneficiaryId); return entities.stream() .map(this::convertEntityToResponse) .collect(Collectors.toList()); } public ApplicationAmendmentRequestResponse closeAmendmentRequest(Long id, CloseAmendmentRequest closeAmendmentRequest){ log.info("Closing application amendement with ID: {}", id); ApplicationAmendmentRequestEntity existingApplicationAmendment = validateApplicationAmendmentRequest(id); setIfUpdated(existingApplicationAmendment::getInternalNote, existingApplicationAmendment::setInternalNote, closeAmendmentRequest.getInternalNote()); setIfUpdated(existingApplicationAmendment::getStatus, existingApplicationAmendment::setStatus, ApplicationAmendmentRequestEnum.CLOSE.getValue()); ApplicationAmendmentRequestEntity updatedApplicationAmendment = saveApplicationAmendmentRequestEntity(existingApplicationAmendment); ApplicationAmendmentRequestResponse response = convertEntityToResponse(updatedApplicationAmendment); log.info("Application Amendment closed successfully: {}", response); return response; } public ApplicationAmendmentRequestResponse extendResponseDays(Long id, Long newResponseDays) { ApplicationAmendmentRequestEntity request = applicationAmendmentRequestRepository.findByIdAndIsDeletedFalse(id) .orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.APPLICATION_AMENDMENT_NOT_FOUND_MSG))); if (newResponseDays != null && newResponseDays > 0) { Long currentResponseDays = request.getResponseDays() != null ? request.getResponseDays() : 0L; request.setResponseDays(currentResponseDays + newResponseDays); applicationAmendmentRequestRepository.save(request); } return convertEntityToResponse(request); } public List getAmendmentByApplicationId(HttpServletRequest request, Long applicationId,List statuses) { log.info("Fetching the Amendment data from application id {}", applicationId); ApplicationEntity application = applicationService.validateApplication(applicationId); List applicationAmendmentRequestEntity=applicationAmendmentRequestRepository.findByApplicationIdAndIsDeletedFalse(applicationId); if(statuses!=null && !statuses.isEmpty()) { List statusStrings = statuses.stream().map(Enum::name).collect(Collectors.toList()); applicationAmendmentRequestEntity = applicationAmendmentRequestRepository.findByApplicationIdAndStatusInAndIsDeletedFalse(application.getId(), statusStrings); } if(!applicationAmendmentRequestEntity.isEmpty()) { ApplicationAmendmentRequestEntity applicationAmendmentRequest=applicationAmendmentRequestEntity.get(0); Optional entityOptional = applicationEvaluationRepository.findByIdAndIsDeletedFalse(applicationAmendmentRequest.getApplicationEvaluationEntity().getId()); if (entityOptional.isPresent()) { if (Boolean.FALSE.equals(validator.checkIsBeneficiary())) { validator.validatePreInstructor(request, entityOptional.get().getUserId()); } else { validator.validateUserId(request, entityOptional.get().getAssignedApplicationsEntity().getApplication().getUserId()); } }} List response=new ArrayList<>(); if(applicationAmendmentRequestEntity!=null) { response= applicationAmendmentRequestEntity.stream() .map(this::convertEntityToResponse) .collect(Collectors.toList()); } return response; } public ApplicationAmendmentRequestResponse updateApplicationAmendmentStatus( Long id,ApplicationAmendmentRequestEnum statusTypeEnum) { log.info("Updating application amendement with status: {}", id); ApplicationAmendmentRequestEntity existingApplicationAmendment = validateApplicationAmendmentRequest(id); if(Boolean.TRUE.equals(existingApplicationAmendment.getStatus().equals(ApplicationAmendmentRequestEnum.AWAITING.getValue())) && Boolean.TRUE.equals(statusTypeEnum.equals(ApplicationAmendmentRequestEnum.RESPONSE_RECEIVED))){ existingApplicationAmendment.setStatus(ApplicationAmendmentRequestEnum.RESPONSE_RECEIVED.getValue()); existingApplicationAmendment.setUpdatedDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); applicationAmendmentRequestRepository.save(existingApplicationAmendment); } ApplicationAmendmentRequestResponse response = convertEntityToResponse(existingApplicationAmendment); log.info("Amendment status updated successfully: {}", response); return response; } public void sendReminderEmail(Long amendmentId) { ApplicationAmendmentRequestEntity amendment = applicationAmendmentRequestRepository.findByIdAndIsDeletedFalse(amendmentId) .orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.APPLICATION_AMENDMENT_NOT_FOUND_MSG))); Optional entityOptional = applicationEvaluationRepository.findByIdAndIsDeletedFalse(amendment.getApplicationEvaluationEntity().getId()); if (entityOptional.isPresent()) { ApplicationEntity applicationEntity = applicationService.validateApplication(entityOptional.get().getApplicationId()); UserEntity beneficiaryUser = userService.validateUser(applicationEntity.getUserId()); HubEntity hub = hubService.valdateHub(applicationEntity.getHubId()); SystemEmailTemplateResponse emailTemplate = systemEmailTemplatesService .retrieveTemplateByTypeAndCall(SystemEmailTemplatesEntityTypeEnum.AMENDMENT_REMINDER, hub, null); String subject = prepareSubject(emailTemplate, amendment, beneficiaryUser); String body = prepareBody(emailTemplate, amendment, beneficiaryUser); String email = beneficiaryUser.getEmail(); if (Boolean.TRUE.equals(amendment.getIsEmail())&&email != null && !email.isEmpty()) { emailNotificationDao.sendMail(hub.getId(), subject, body, List.of(email)); } else { throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.BENEFICIARY_EMAIL_NOT_FOUND_MSG)); } } } private String prepareSubject(SystemEmailTemplateResponse template, ApplicationAmendmentRequestEntity amendment, UserEntity beneficiary) { Map subjectPlaceholders = new HashMap<>(); String firstName = beneficiary.getFirstName() != null ? beneficiary.getFirstName() : ""; String lastName = beneficiary.getLastName() != null ? beneficiary.getLastName() : ""; String beneficiaryName = String.join(" ", firstName, lastName).trim(); subjectPlaceholders.put("{{amendment_id}}", amendment.getId().toString()); subjectPlaceholders.put("{{beneficiary_name}}", beneficiaryName); return Utils.replacePlaceholders(template.getSubject(), subjectPlaceholders); } private String prepareBody(SystemEmailTemplateResponse template, ApplicationAmendmentRequestEntity amendment, UserEntity beneficiary) { Map bodyPlaceholders = new HashMap<>(); bodyPlaceholders.put("{{amendment_id}}", amendment.getId().toString()); if (amendment.getStartDate() != null && amendment.getResponseDays() != null) { LocalDateTime dueDate = amendment.getStartDate().plusDays(amendment.getResponseDays()); bodyPlaceholders.put("{{amendment_due_date}}", DateTimeUtil.formatLocalDateTime(dueDate, GepafinConstant.DD_MM_YYYY)); } else { bodyPlaceholders.put("{{amendment_due_date}}", "Not available"); } return Utils.replacePlaceholders(template.getHtmlContent(), bodyPlaceholders); } }