Files
bflows-bandi-be/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java
rajeshkhore 0f3b5208dc Merge pull request #93 from Kitzanos/feature/GEPAFINBE-93
GEPAFINBE-93(Issue with Evaluation Status)
2024-11-14 17:06:29 +05:30

773 lines
42 KiB
Java

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.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.entities.SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum;
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.Utils;
import net.gepafin.tendermanagement.util.Validator;
import net.gepafin.tendermanagement.web.rest.api.errors.CustomValidationException;
import net.gepafin.tendermanagement.web.rest.api.errors.ResourceNotFoundException;
import net.gepafin.tendermanagement.web.rest.api.errors.Status;
import org.springframework.beans.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.LocalDateTime;
import java.time.temporal.ChronoUnit;
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<ApplicationFormEntity> forms = applicationFormRepository.findByApplicationId(applicationId);
List<AmendmentFormFieldResponse> allFormFields = new ArrayList<>();
for (ApplicationFormEntity form : forms) {
String content = form.getForm().getContent();
List<Map<String, Object>> result = filterByName(content, "fileupload");
allFormFields.addAll(getIdAndLabelFromResult(result));
}
response.setFormFields(allFormFields);
return response;
}
public List<AmendmentFormFieldResponse> getIdAndLabelFromResult(List<Map<String, Object>> result) {
List<AmendmentFormFieldResponse> formFieldResponses = new ArrayList<>();
for (Map<String, Object> item : result) {
AmendmentFormFieldResponse formFieldResponse = new AmendmentFormFieldResponse();
formFieldResponse.setFieldId((String) item.get("id"));
// Extract "label" value from the "settings" array
List<Map<String, Object>> settings = (List<Map<String, Object>>) 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<Map<String, Object>> filterByName(String content, String target) {
ObjectMapper objectMapper = new ObjectMapper();
List<Map<String, Object>> filteredList = new ArrayList<>();
try {
List<Map<String, Object>> dataList = objectMapper.readValue(
content, new TypeReference<List<Map<String, Object>>>() {
});
for (Map<String, Object> 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.getIsSendEmail())) {
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) {
List<ApplicationFormFieldRequestBean> formFieldRequestBean = applicationAmendmentRequest.getFormFields().stream()
.filter(AmendmentFormFieldResponse::isSelected)
.map(amendmentFormFieldRequest -> {
ApplicationFormFieldRequestBean formField = new ApplicationFormFieldRequestBean();
formField.setFieldId(amendmentFormFieldRequest.getFieldId());
formField.setFieldValue(null);
return formField;
})
.collect(Collectors.toList());
String formFieldsJson = Utils.convertObjectToJson(formFieldRequestBean);
applicationAmendmentRequestEntity.setFormFields(formFieldsJson);
}
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.setIsSendEmail(applicationAmendmentRequestEntity.getIsEmail());
applicationAmendmentRequestResponse.setIsSendNotification(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);
List<ApplicationFormEntity> forms = applicationFormRepository.findByApplicationId(applicationId);
List<AmendmentFormFieldResponse> allFormFields = new ArrayList<>();
for (ApplicationFormEntity form : forms) {
String content = form.getForm().getContent();
List<Map<String, Object>> result = filterByName(content, "fileupload");
allFormFields.addAll(getIdAndLabelFromResult(result));
}
Map<String, String> fieldIdToLabelMap = allFormFields.stream()
.collect(Collectors.toMap(AmendmentFormFieldResponse::getFieldId, AmendmentFormFieldResponse::getLabel));
String formFieldsJson = applicationAmendmentRequestEntity.getFormFields();
List<AmendmentFormFieldResponse> formFields = Utils.convertJsonToList(
formFieldsJson, new TypeReference<List<AmendmentFormFieldResponse>>() {
});
for (AmendmentFormFieldResponse formField : formFields) {
String label = fieldIdToLabelMap.get(formField.getFieldId());
formField.setLabel(label);
formField.setSelected(true);
}
// Set the filtered formFields in the response
applicationAmendmentRequestResponse.setFormFields(formFields);
String applicationFormFieldsJson = applicationAmendmentRequestEntity.getFormFields();
List<ApplicationFormFieldResponseBean> applicationFormFields = Utils.convertJsonToList(
formFieldsJson, new TypeReference<List<ApplicationFormFieldResponseBean>>() {
});
List<ApplicationFormFieldResponseBean> fileDetailResponses = new ArrayList<>();
for (ApplicationFormFieldResponseBean field : applicationFormFields) {
ApplicationFormFieldResponseBean responseBean = new ApplicationFormFieldResponseBean();
responseBean.setFieldId(field.getFieldId());
Optional<ApplicationFormFieldEntity> formFieldEntity = Optional.empty();
for (ApplicationFormEntity form : forms) {
formFieldEntity = applicationFormFieldRepository
.findByApplicationFormIdAndFieldId(form.getId(), field.getFieldId());
if (formFieldEntity.isPresent()) {
// Set the applicationFormId from the matching form
responseBean.setApplicationFormId(form.getId());
responseBean.setId(formFieldEntity.get().getId());
responseBean.setCreatedDate(formFieldEntity.get().getCreatedDate());
responseBean.setUpdatedDate(formFieldEntity.get().getUpdatedDate());
break;
}
}
// Check if fieldValue is not null and is a String
if (field.getFieldValue() instanceof String && field.getFieldValue() != null && !((String) field.getFieldValue()).isBlank()) {
String fieldValueString = (String) field.getFieldValue();
String[] documentIds = fieldValueString.split(",");
List<DocumentResponseBean> documentResponseBeans = new ArrayList<>();
// Process each document ID
for (String docId : documentIds) {
try {
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);
});
} catch (NumberFormatException e) {
// Handle the case where documentId is not a valid number
// Log the error if necessary
}
}
responseBean.setFieldValue(documentResponseBeans);
} else {
responseBean.setFieldValue(null);
}
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<ApplicationAmendmentRequestResponse> 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<ApplicationAmendmentRequestEntity> spec = search(userId);
List<ApplicationAmendmentRequestEntity> applicationAmendmentRequestEntities =
applicationAmendmentRequestRepository.findAll(spec);
return applicationAmendmentRequestEntities.stream()
.map(this::convertEntityToResponse)
.collect(Collectors.toList());
}
private Specification<ApplicationAmendmentRequestEntity> search(Long userId) {
return (root, query, builder) -> {
Predicate predicate = builder.isFalse(root.get("isDeleted")); // Only non-deleted records
if (userId != null) {
Join<Object, Object> 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());
updateFormFieldsJson(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<ApplicationFormEntity> applicationForms = applicationFormRepository.findByApplicationId(applicationAmendment.getApplicationId());
boolean fieldUpdated = false;
for (ApplicationFormEntity applicationForm : applicationForms) {
Optional<ApplicationFormFieldEntity> 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<String> 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<String> 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<ApplicationFormEntity> applicationForms = applicationFormRepository.findByApplicationId(applicationAmendment.getApplicationId());
boolean fieldUpdated = false;
// Parse the formFields JSON string to get amendment field values
String amendmentFieldValue = null;
try {
ObjectMapper mapper = new ObjectMapper();
List<ApplicationFormFieldRequestBean> amendmentFields = mapper.readValue(
applicationAmendment.getFormFields(),
mapper.getTypeFactory().constructCollectionType(List.class, ApplicationFormFieldRequestBean.class)
);
// Find the matching field value and convert to string if found
Optional<Object> amendmentFieldObj = amendmentFields.stream()
.filter(field -> updatedFormField.getFieldId().equals(field.getFieldId()))
.map(ApplicationFormFieldRequestBean::getFieldValue)
.findFirst();
if (amendmentFieldObj.isPresent() && amendmentFieldObj.get() instanceof String) {
amendmentFieldValue = (String) amendmentFieldObj.get();
}
} catch (JsonProcessingException e) {
log.error("Error parsing formFields JSON: {}", e.getMessage());
return;
}
if (amendmentFieldValue == null) {
log.warn("No matching field found in amendment for field ID {}", updatedFormField.getFieldId());
return;
}
List<String> amendmentDocumentIds = Arrays.asList(amendmentFieldValue.split(","));
for (ApplicationFormEntity applicationForm : applicationForms) {
Optional<ApplicationFormFieldEntity> formFieldEntityOptional = applicationFormFieldRepository
.findByApplicationFormIdAndFieldId(applicationForm.getId(), updatedFormField.getFieldId());
if (formFieldEntityOptional.isPresent()) {
ApplicationFormFieldEntity formEntity = formFieldEntityOptional.get();
// Retrieve existing document IDs in ApplicationFormFieldTable
String existingFieldValue = formEntity.getFieldValue();
Set<String> existingDocumentIds = existingFieldValue != null
? new HashSet<>(Arrays.asList(existingFieldValue.split(",")))
: new HashSet<>();
// Remove amendment documents from existing document IDs
existingDocumentIds.removeAll(amendmentDocumentIds);
// Add valid new document IDs from the request
existingDocumentIds.addAll(validDocumentIds);
// Set the combined document IDs back as the field value
formEntity.setFieldValue(String.join(",", existingDocumentIds));
applicationFormFieldRepository.save(formEntity);
log.info("Updated field value for application ID {} and field ID {} with document IDs {}",
applicationAmendment.getApplicationId(), updatedFormField.getFieldId(), String.join(",", existingDocumentIds));
fieldUpdated = true;
break;
}
}
if (!fieldUpdated) {
throw new CustomValidationException(Status.NOT_FOUND,
String.format("No ApplicationFormField found for application ID %s and field ID %s. Skipping update.",
applicationAmendment.getApplicationId(), updatedFormField.getFieldId()));
}
} else {
log.warn("No valid document IDs found for update. Skipping field ID {}", updatedFormField.getFieldId());
}
}
private void updateFormFieldsJson(ApplicationAmendmentRequestEntity applicationAmendment, ApplicationFormFieldRequestBean updatedFormField) {
if (updatedFormField != null) {
try {
// Step 1: Fetch the existing form fields JSON
String existingFormFieldsJson = applicationAmendment.getFormFields();
List<ApplicationFormFieldRequestBean> formFieldsList;
if (existingFormFieldsJson == null || existingFormFieldsJson.isEmpty()) {
formFieldsList = new ArrayList<>(); // If no existing data, start with an empty list
} else {
// Step 2: Deserialize the existing JSON into a list of objects
formFieldsList = new ObjectMapper().readValue(existingFormFieldsJson, new TypeReference<List<ApplicationFormFieldRequestBean>>() {
});
}
// Step 3: Check if the field ID already exists in the list and update it
boolean fieldUpdated = false;
for (ApplicationFormFieldRequestBean field : formFieldsList) {
if (field.getFieldId().equals(updatedFormField.getFieldId())) {
field.setFieldValue(updatedFormField.getFieldValue()); // Update field value
fieldUpdated = true;
break;
}
}
// If field wasn't updated, log a warning message instead of adding a new field
if (!fieldUpdated) {
log.warn("Field ID {} does not exist in the form fields for application amendment ID {}", updatedFormField.getFieldId(), applicationAmendment.getId());
throw new CustomValidationException(Status.NOT_FOUND, "Field ID {} does not exist in the form fields for application amendment ID {}");
}
// Step 4: Serialize the updated list back to JSON if the update was successful
String updatedFormFieldsJson = new ObjectMapper().writeValueAsString(formFieldsList);
applicationAmendment.setFormFields(updatedFormFieldsJson); // Update the form fields with the modified list
log.info("Updated form fields JSON for application amendment ID {}: {}", applicationAmendment.getId(), updatedFormFieldsJson);
} catch (JsonProcessingException e) {
log.error("Error processing JSON for form fields for application amendment ID {}: {}", applicationAmendment.getId(), e.getMessage());
throw new CustomValidationException(Status.BAD_REQUEST, "Error processing JSON for form fields");
}
} else {
log.warn("No form field data to update for application amendment ID {}", applicationAmendment.getId());
throw new CustomValidationException(Status.NOT_FOUND, "No form field data to update for application amendment ID {}");
}
}
public List<ApplicationAmendmentRequestResponse> getAllAmendmentRequestByBeneficiaryId(Long beneficiaryId) {
UserEntity userEntity = userService.validateUser(beneficiaryId);
List<ApplicationAmendmentRequestEntity> 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);
List<ApplicationAmendmentRequestEntity> amendmentRequests = applicationAmendmentRequestRepository.findAllByApplicationEvaluationIdAndIsDeletedFalse(existingApplicationAmendment.getApplicationEvaluationEntity().getId());
boolean allClosed = amendmentRequests.stream()
.allMatch(amendment -> amendment.getStatus().equals(ApplicationAmendmentRequestEnum.CLOSE.getValue()));
if (allClosed) {
existingApplicationAmendment.getApplicationEvaluationEntity().setStatus(ApplicationEvaluationStatusTypeEnum.OPEN.getValue());
applicationEvaluationRepository.save(existingApplicationAmendment.getApplicationEvaluationEntity());
log.info("All amendments are closed. Application Evaluation status set to OPEN.");
}
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<ApplicationAmendmentRequestResponse> getAmendmentByApplicationId(HttpServletRequest request, Long applicationId, List<ApplicationAmendmentRequestEnum> statuses) {
log.info("Fetching the Amendment data from application id {}", applicationId);
ApplicationEntity application = applicationService.validateApplication(applicationId);
List<ApplicationAmendmentRequestEntity> applicationAmendmentRequestEntity = applicationAmendmentRequestRepository.findByApplicationIdAndIsDeletedFalse(applicationId);
if (statuses != null && !statuses.isEmpty()) {
List<String> statusStrings = statuses.stream().map(Enum::name).collect(Collectors.toList());
applicationAmendmentRequestEntity = applicationAmendmentRequestRepository.findByApplicationIdAndStatusInAndIsDeletedFalse(application.getId(), statusStrings);
}
if (!applicationAmendmentRequestEntity.isEmpty()) {
ApplicationAmendmentRequestEntity applicationAmendmentRequest = applicationAmendmentRequestEntity.get(0);
Optional<ApplicationEvaluationEntity> 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<ApplicationAmendmentRequestResponse> 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<ApplicationEvaluationEntity> 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<String, String> 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<String, String> 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);
}
}