Created CRUD for ApplicationEvaluation Entity
This commit is contained in:
@@ -233,5 +233,13 @@ public class GepafinConstant {
|
|||||||
public static final String CANNOT_DELETE_COMPANY_WITH_APPLICATION_SUBMITT = "application.in.submit.status.cannot.delete.company";
|
public static final String CANNOT_DELETE_COMPANY_WITH_APPLICATION_SUBMITT = "application.in.submit.status.cannot.delete.company";
|
||||||
public static final String GET_USERS_SUCCESS_MSG = "get.users.success.msg";
|
public static final String GET_USERS_SUCCESS_MSG = "get.users.success.msg";
|
||||||
public static final String CANNOT_CREATE_BENEFICIARY_USER="cannot.create.beneficiary.user";
|
public static final String CANNOT_CREATE_BENEFICIARY_USER="cannot.create.beneficiary.user";
|
||||||
|
public static final String EVALUATION_CREATED_SUCCESSFULLY = "evaluation.created.successfully";
|
||||||
|
public static final String EVALUATION_UPDATED_SUCCESSFULLY = "evaluation.updated.successfully";
|
||||||
|
public static final String EVALUATION_FETCHED_SUCCESSFULLY = "evaluation.fetched.successfully";
|
||||||
|
public static final String EVALUATION_DELETED_SUCCESSFULLY = "evaluation.deleted.successfully";
|
||||||
|
public static final String EVALUATIONS_FETCHED_SUCCESSFULLY = "evaluations.fetched.successfully";
|
||||||
|
public static final String APPLICATION_EVALUATION_NOT_FOUND = "application.evaluation.not.found";
|
||||||
|
public static final String APPLICATION_EVALUATION_STATUS_UPDATED_SUCCESSFULLY = "application.evaluation.status.updated.successfully";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,554 @@
|
|||||||
|
package net.gepafin.tendermanagement.dao;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.type.TypeReference;
|
||||||
|
import net.gepafin.tendermanagement.config.Translator;
|
||||||
|
import net.gepafin.tendermanagement.constants.GepafinConstant;
|
||||||
|
import net.gepafin.tendermanagement.entities.*;
|
||||||
|
import net.gepafin.tendermanagement.enums.ApplicationEvaluationStatusTypeEnum;
|
||||||
|
import net.gepafin.tendermanagement.enums.ApplicationStatusTypeEnum;
|
||||||
|
import net.gepafin.tendermanagement.enums.DocumentSourceTypeEnum;
|
||||||
|
import net.gepafin.tendermanagement.enums.DocumentTypeEnum;
|
||||||
|
import net.gepafin.tendermanagement.model.request.ApplicationEvaluationRequest;
|
||||||
|
import net.gepafin.tendermanagement.model.request.ChecklistRequest;
|
||||||
|
import net.gepafin.tendermanagement.model.request.CriteriaRequest;
|
||||||
|
import net.gepafin.tendermanagement.model.request.FieldRequest;
|
||||||
|
import net.gepafin.tendermanagement.model.response.*;
|
||||||
|
import net.gepafin.tendermanagement.repositories.*;
|
||||||
|
import net.gepafin.tendermanagement.service.ApplicationService;
|
||||||
|
import net.gepafin.tendermanagement.service.UserService;
|
||||||
|
import net.gepafin.tendermanagement.util.Utils;
|
||||||
|
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.stereotype.Component;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import static net.gepafin.tendermanagement.util.Utils.setIfUpdated;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class ApplicationEvaluationDao {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ApplicationEvaluationRepository applicationEvaluationRepository;
|
||||||
|
@Autowired
|
||||||
|
private ApplicationService applicationService;
|
||||||
|
@Autowired
|
||||||
|
private CallRepository callRepository;
|
||||||
|
@Autowired
|
||||||
|
private ApplicationRepository applicationRepository;
|
||||||
|
@Autowired
|
||||||
|
private UserService userService;
|
||||||
|
@Autowired
|
||||||
|
private EvaluationCriteriaRepository evaluationCriteriaRepository;
|
||||||
|
@Autowired
|
||||||
|
private FormRepository formRepository;
|
||||||
|
@Autowired
|
||||||
|
private CallTargetAudienceChecklistRepository callTargetAudienceChecklistRepository;
|
||||||
|
@Autowired
|
||||||
|
private DocumentRepository documentRepository;
|
||||||
|
@Autowired
|
||||||
|
private ApplicationFormRepository applicationFormRepository;
|
||||||
|
@Autowired
|
||||||
|
private ApplicationFormFieldRepository applicationFormFieldRepository;
|
||||||
|
|
||||||
|
private ApplicationEvaluationEntity convertToEntity(UserEntity user, ApplicationEvaluationRequest req) {
|
||||||
|
ApplicationEvaluationEntity entity = new ApplicationEvaluationEntity();
|
||||||
|
ApplicationEntity application = applicationService.validateApplication(req.getApplicationId());
|
||||||
|
entity.setApplication(application);
|
||||||
|
entity.setUserId(user.getId());
|
||||||
|
entity.setCriteria(Utils.convertObjectToJson(req.getCriteria()));
|
||||||
|
entity.setChecklist(Utils.convertObjectToJson(req.getChecklist()));
|
||||||
|
entity.setFile(Utils.convertObjectToJson(req.getField()));
|
||||||
|
entity.setNote(req.getNote());
|
||||||
|
entity.setIsDeleted(false);
|
||||||
|
entity.setStatus(ApplicationEvaluationStatusTypeEnum.DRAFT.getValue());
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ApplicationEvaluationResponse convertToResponse(ApplicationEvaluationEntity entity) {
|
||||||
|
ApplicationEvaluationResponse response = new ApplicationEvaluationResponse();
|
||||||
|
populateBasicDetails(entity, response);
|
||||||
|
|
||||||
|
CallEntity call = callRepository.findCallEntityByApplicationId(entity.getApplication().getId());
|
||||||
|
List<EvaluationCriteriaEntity> evaluationCriterias = evaluationCriteriaRepository.findByCallId(call.getId());
|
||||||
|
List<CallTargetAudienceChecklistEntity> checklistEntities = callTargetAudienceChecklistRepository.findByCallId(call.getId());
|
||||||
|
List<ApplicationFormEntity> applicationFormEntities = applicationFormRepository.findByApplicationId(entity.getApplication().getId());
|
||||||
|
|
||||||
|
setCriteriaResponses(entity, response, evaluationCriterias);
|
||||||
|
setChecklistResponses(entity, response, checklistEntities);
|
||||||
|
setFieldResponses(entity, response, applicationFormEntities);
|
||||||
|
|
||||||
|
setApplicationDetails(response, entity);
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void populateBasicDetails(ApplicationEvaluationEntity entity, ApplicationEvaluationResponse response) {
|
||||||
|
response.setId(entity.getId());
|
||||||
|
response.setApplicationId(entity.getApplication().getId());
|
||||||
|
response.setNote(entity.getNote());
|
||||||
|
response.setStatus(ApplicationEvaluationStatusTypeEnum.valueOf(entity.getStatus()));
|
||||||
|
response.setCreatedDate(entity.getCreatedDate());
|
||||||
|
response.setUpdatedDate(entity.getUpdatedDate());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setCriteriaResponses(ApplicationEvaluationEntity entity, ApplicationEvaluationResponse response, List<EvaluationCriteriaEntity> evaluationCriterias) {
|
||||||
|
List<CriteriaResponse> criteriaResponsesFromEntity = entity.getCriteria() != null
|
||||||
|
? Utils.convertJsonToList(entity.getCriteria(), new TypeReference<List<CriteriaResponse>>() {})
|
||||||
|
: new ArrayList<>();
|
||||||
|
|
||||||
|
List<CriteriaResponse> criteriaResponsesFromDB = getCriteriaResponse(entity.getApplication().getId());
|
||||||
|
addMissingCriteriaResponses(criteriaResponsesFromEntity, criteriaResponsesFromDB);
|
||||||
|
|
||||||
|
criteriaResponsesFromEntity.forEach(criteriaResponse -> {
|
||||||
|
EvaluationCriteriaEntity matchingEvaluationCriteria = evaluationCriterias.stream()
|
||||||
|
.filter(evaluationCriteria -> evaluationCriteria.getId().equals(criteriaResponse.getId()))
|
||||||
|
.findFirst()
|
||||||
|
.orElse(null);
|
||||||
|
|
||||||
|
if (matchingEvaluationCriteria != null) {
|
||||||
|
criteriaResponse.setLabel(matchingEvaluationCriteria.getLookupData().getValue());
|
||||||
|
criteriaResponse.setMaxScore(matchingEvaluationCriteria.getScore());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
response.setCriteria(criteriaResponsesFromEntity);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addMissingCriteriaResponses(List<CriteriaResponse> criteriaResponsesFromEntity, List<CriteriaResponse> criteriaResponsesFromDB) {
|
||||||
|
Set<Long> existingCriteriaIds = criteriaResponsesFromEntity.stream()
|
||||||
|
.map(CriteriaResponse::getId)
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
|
||||||
|
for (CriteriaResponse dbResponse : criteriaResponsesFromDB) {
|
||||||
|
if (!existingCriteriaIds.contains(dbResponse.getId())) {
|
||||||
|
criteriaResponsesFromEntity.add(dbResponse);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setChecklistResponses(ApplicationEvaluationEntity entity, ApplicationEvaluationResponse response, List<CallTargetAudienceChecklistEntity> checklistEntities) {
|
||||||
|
List<ChecklistResponse> checklistResponsesFromEntity = entity.getChecklist() != null
|
||||||
|
? Utils.convertJsonToList(entity.getChecklist(), new TypeReference<List<ChecklistResponse>>() {})
|
||||||
|
: new ArrayList<>();
|
||||||
|
|
||||||
|
List<ChecklistResponse> checklistResponsesFromDB = getChecklistResponse(entity.getApplication().getId());
|
||||||
|
addMissingChecklistResponses(checklistResponsesFromEntity, checklistResponsesFromDB);
|
||||||
|
|
||||||
|
checklistResponsesFromEntity.forEach(checklistResponse -> {
|
||||||
|
CallTargetAudienceChecklistEntity matchingChecklist = checklistEntities.stream()
|
||||||
|
.filter(checklistEntity -> checklistEntity.getId().equals(checklistResponse.getId()))
|
||||||
|
.findFirst()
|
||||||
|
.orElse(null);
|
||||||
|
|
||||||
|
if (matchingChecklist != null) {
|
||||||
|
checklistResponse.setLabel(matchingChecklist.getLookupData().getValue());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
response.setChecklist(checklistResponsesFromEntity);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addMissingChecklistResponses(List<ChecklistResponse> checklistResponsesFromEntity, List<ChecklistResponse> checklistResponsesFromDB) {
|
||||||
|
Set<Long> existingChecklistIds = checklistResponsesFromEntity.stream()
|
||||||
|
.map(ChecklistResponse::getId)
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
|
||||||
|
for (ChecklistResponse dbResponse : checklistResponsesFromDB) {
|
||||||
|
if (!existingChecklistIds.contains(dbResponse.getId())) {
|
||||||
|
checklistResponsesFromEntity.add(dbResponse);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setFieldResponses(ApplicationEvaluationEntity entity, ApplicationEvaluationResponse response, List<ApplicationFormEntity> applicationFormEntities) {
|
||||||
|
List<FieldResponse> fieldResponsesFromEntity = entity.getFile() != null
|
||||||
|
? Utils.convertJsonToList(entity.getFile(), new TypeReference<List<FieldResponse>>() {})
|
||||||
|
: new ArrayList<>();
|
||||||
|
|
||||||
|
List<FieldResponse> fieldResponsesFromDB = getFieldResponses(entity.getApplication().getId());
|
||||||
|
addMissingFieldResponses(fieldResponsesFromEntity, fieldResponsesFromDB);
|
||||||
|
|
||||||
|
fieldResponsesFromEntity.forEach(fieldResponse -> {
|
||||||
|
applicationFormEntities.forEach(applicationForm -> {
|
||||||
|
FormEntity formEntity = applicationForm.getForm();
|
||||||
|
if (formEntity != null) {
|
||||||
|
List<ContentResponseBean> contentResponseBeans = Utils.convertJsonStringToList(formEntity.getContent(), ContentResponseBean.class);
|
||||||
|
contentResponseBeans.forEach(contentResponseBean -> {
|
||||||
|
if ("fileupload".equals(contentResponseBean.getName()) && contentResponseBean.getId().equals(fieldResponse.getId())) {
|
||||||
|
fieldResponse.setLabel(contentResponseBean.getLabel());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
response.setFiles(fieldResponsesFromEntity);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addMissingFieldResponses(List<FieldResponse> fieldResponsesFromEntity, List<FieldResponse> fieldResponsesFromDB) {
|
||||||
|
Set<String> existingFieldIds = fieldResponsesFromEntity.stream()
|
||||||
|
.map(FieldResponse::getId)
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
|
||||||
|
for (FieldResponse dbResponse : fieldResponsesFromDB) {
|
||||||
|
if (!existingFieldIds.contains(dbResponse.getId())) {
|
||||||
|
fieldResponsesFromEntity.add(dbResponse);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setApplicationDetails(ApplicationEvaluationResponse response, ApplicationEvaluationEntity entity) {
|
||||||
|
ApplicationEntity application = applicationService.validateApplication(entity.getApplication() != null ? entity.getApplication().getId() : null);
|
||||||
|
UserEntity user = userService.validateUser(application.getUserId());
|
||||||
|
String firstName = user.getFirstName() != null ? user.getFirstName() : "";
|
||||||
|
String lastName = user.getLastName() != null ? user.getLastName() : "";
|
||||||
|
|
||||||
|
String beneficiary = String.join(" ", firstName, lastName).trim();
|
||||||
|
response.setBeneficiary(beneficiary);
|
||||||
|
|
||||||
|
response.setCallName(application.getCall().getName());
|
||||||
|
response.setProtocolNumber(application.getProtocol() != null ? application.getProtocol().getProtocolNumber() : null);
|
||||||
|
response.setSubmissionDate(application.getSubmissionDate());
|
||||||
|
response.setEvaluationDate(LocalDateTime.now());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public ApplicationEvaluationResponse createOrUpdateApplicationEvaluation(UserEntity user, ApplicationEvaluationRequest req) {
|
||||||
|
Optional<ApplicationEvaluationEntity> existingEntityOptional = applicationEvaluationRepository.findByApplicationId(req.getApplicationId());
|
||||||
|
ApplicationEvaluationEntity entity;
|
||||||
|
|
||||||
|
if (existingEntityOptional.isPresent()) {
|
||||||
|
entity = existingEntityOptional.get();
|
||||||
|
entity.setCriteria(Utils.convertObjectToJson(processCriteria(entity, req)));
|
||||||
|
entity.setChecklist(Utils.convertObjectToJson(processChecklist(entity, req)));
|
||||||
|
entity.setFile(Utils.convertObjectToJson(processField(entity, req)));
|
||||||
|
entity.setIsDeleted(false);
|
||||||
|
setIfUpdated(entity::getNote, entity::setNote, req.getNote());
|
||||||
|
} else {
|
||||||
|
entity = convertToEntity(user, req);
|
||||||
|
}
|
||||||
|
|
||||||
|
ApplicationEvaluationEntity savedEntity = applicationEvaluationRepository.save(entity);
|
||||||
|
return convertToResponse(savedEntity);
|
||||||
|
}
|
||||||
|
private List<CriteriaRequest> processCriteria(ApplicationEvaluationEntity entity, ApplicationEvaluationRequest req) {
|
||||||
|
List<CriteriaResponse> existingCriteriaList = entity.getCriteria() != null ?
|
||||||
|
Utils.convertJsonToList(entity.getCriteria(), new TypeReference<List<CriteriaResponse>>() {}) : new ArrayList<>();
|
||||||
|
|
||||||
|
Map<Long, CriteriaResponse> existingCriteriaMap = existingCriteriaList.stream()
|
||||||
|
.collect(Collectors.toMap(CriteriaResponse::getId, criteria -> criteria));
|
||||||
|
|
||||||
|
List<CriteriaRequest> updatedCriteriaList = req.getCriteria().stream()
|
||||||
|
.map(incoming -> {
|
||||||
|
CriteriaRequest request = new CriteriaRequest();
|
||||||
|
request.setId(incoming.getId());
|
||||||
|
request.setScore(incoming.getScore());
|
||||||
|
request.setValid(incoming.getValid());
|
||||||
|
|
||||||
|
CriteriaResponse existingCriteria = existingCriteriaMap.get(incoming.getId());
|
||||||
|
if (existingCriteria != null) {
|
||||||
|
request.setScore(incoming.getScore() != null ? incoming.getScore() : existingCriteria.getScore());
|
||||||
|
request.setValid(incoming.getValid() != null ? incoming.getValid() : existingCriteria.getValid());
|
||||||
|
}
|
||||||
|
return request;
|
||||||
|
})
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
List<CriteriaRequest> missingCriteriaRequests = existingCriteriaList.stream()
|
||||||
|
.filter(existing -> !updatedCriteriaList.stream()
|
||||||
|
.map(CriteriaRequest::getId)
|
||||||
|
.toList()
|
||||||
|
.contains(existing.getId()))
|
||||||
|
.map(existing -> {
|
||||||
|
CriteriaRequest request = new CriteriaRequest();
|
||||||
|
request.setId(existing.getId());
|
||||||
|
request.setScore(existing.getScore());
|
||||||
|
request.setValid(existing.getValid());
|
||||||
|
return request;
|
||||||
|
})
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
updatedCriteriaList.addAll(missingCriteriaRequests);
|
||||||
|
return updatedCriteriaList;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<ChecklistRequest> processChecklist(ApplicationEvaluationEntity entity, ApplicationEvaluationRequest req) {
|
||||||
|
List<ChecklistResponse> existingChecklistList = entity.getChecklist() != null ?
|
||||||
|
Utils.convertJsonToList(entity.getChecklist(), new TypeReference<List<ChecklistResponse>>() {}) : new ArrayList<>();
|
||||||
|
|
||||||
|
Map<Long, ChecklistResponse> existingChecklistMap = existingChecklistList.stream()
|
||||||
|
.collect(Collectors.toMap(ChecklistResponse::getId, checklist -> checklist));
|
||||||
|
|
||||||
|
List<ChecklistRequest> updatedChecklistList = req.getChecklist().stream()
|
||||||
|
.map(incoming -> {
|
||||||
|
ChecklistRequest request = new ChecklistRequest();
|
||||||
|
request.setId(incoming.getId());
|
||||||
|
request.setValid(incoming.getValid());
|
||||||
|
|
||||||
|
ChecklistResponse existingChecklist = existingChecklistMap.get(incoming.getId());
|
||||||
|
if (existingChecklist != null) {
|
||||||
|
request.setValid(incoming.getValid() != null ? incoming.getValid() : existingChecklist.getValid());
|
||||||
|
}
|
||||||
|
return request;
|
||||||
|
})
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
List<ChecklistRequest> missingChecklistRequests = existingChecklistList.stream()
|
||||||
|
.filter(existing -> !updatedChecklistList.stream()
|
||||||
|
.map(ChecklistRequest::getId)
|
||||||
|
.toList()
|
||||||
|
.contains(existing.getId()))
|
||||||
|
.map(existing -> {
|
||||||
|
ChecklistRequest request = new ChecklistRequest();
|
||||||
|
request.setId(existing.getId());
|
||||||
|
request.setValid(existing.getValid());
|
||||||
|
return request;
|
||||||
|
})
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
updatedChecklistList.addAll(missingChecklistRequests);
|
||||||
|
return updatedChecklistList;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<FieldRequest> processField(ApplicationEvaluationEntity entity, ApplicationEvaluationRequest req) {
|
||||||
|
List<FieldResponse> existingFieldList = entity.getFile() != null ?
|
||||||
|
Utils.convertJsonToList(entity.getFile(), new TypeReference<List<FieldResponse>>() {}) : new ArrayList<>();
|
||||||
|
|
||||||
|
Map<String, FieldResponse> existingFieldMap = existingFieldList.stream()
|
||||||
|
.collect(Collectors.toMap(FieldResponse::getId, field -> field));
|
||||||
|
|
||||||
|
List<FieldRequest> updatedFieldList = req.getField().stream()
|
||||||
|
.map(incoming -> {
|
||||||
|
FieldRequest request = new FieldRequest();
|
||||||
|
request.setId(incoming.getId());
|
||||||
|
request.setValid(incoming.getValid());
|
||||||
|
|
||||||
|
FieldResponse existingField = existingFieldMap.get(incoming.getId());
|
||||||
|
if (existingField != null) {
|
||||||
|
request.setValid(incoming.getValid() != null ? incoming.getValid() : existingField.getValid());
|
||||||
|
}
|
||||||
|
return request;
|
||||||
|
})
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
List<FieldRequest> missingFieldRequests = existingFieldList.stream()
|
||||||
|
.filter(existing -> !updatedFieldList.stream()
|
||||||
|
.map(FieldRequest::getId)
|
||||||
|
.toList()
|
||||||
|
.contains(existing.getId()))
|
||||||
|
.map(existing -> {
|
||||||
|
FieldRequest request = new FieldRequest();
|
||||||
|
request.setId(existing.getId());
|
||||||
|
request.setValid(existing.getValid());
|
||||||
|
return request;
|
||||||
|
})
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
updatedFieldList.addAll(missingFieldRequests);
|
||||||
|
return updatedFieldList;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ApplicationEvaluationEntity validateApplicationEvaluation(Long id) {
|
||||||
|
Optional<ApplicationEvaluationEntity> entityOptional = applicationEvaluationRepository.findById(id);
|
||||||
|
if (entityOptional.isEmpty()) {
|
||||||
|
throw new ResourceNotFoundException(Status.NOT_FOUND,
|
||||||
|
Translator.toLocale(GepafinConstant.APPLICATION_EVALUATION_NOT_FOUND, id));
|
||||||
|
}
|
||||||
|
return entityOptional.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public ApplicationEvaluationResponse getApplicationEvaluationByApplicationId(UserEntity user, Long applicationId) {
|
||||||
|
applicationService.validateApplication(applicationId);
|
||||||
|
Optional<ApplicationEvaluationEntity> entityOptional = applicationEvaluationRepository.findByApplicationId(applicationId);
|
||||||
|
return entityOptional.map(this::convertToResponse).orElseGet(() -> getEvaluationResponseByApplicationid(user, applicationId));
|
||||||
|
|
||||||
|
}
|
||||||
|
public ApplicationEvaluationResponse getEvaluationResponseByApplicationid(UserEntity user, Long applicationId) {
|
||||||
|
ApplicationEvaluationEntity entity = new ApplicationEvaluationEntity();
|
||||||
|
ApplicationEvaluationResponse response = new ApplicationEvaluationResponse();
|
||||||
|
|
||||||
|
CallEntity call = callRepository.findCallEntityByApplicationId(applicationId);
|
||||||
|
List<EvaluationCriteriaEntity> evaluationCriterias = evaluationCriteriaRepository.findByCallId(call.getId());
|
||||||
|
List<CallTargetAudienceChecklistEntity> checklistEntities = callTargetAudienceChecklistRepository.findByCallId(call.getId());
|
||||||
|
List<ApplicationFormEntity> applicationFormEntities = applicationFormRepository.findByApplicationId(applicationId);
|
||||||
|
|
||||||
|
response.setApplicationId(applicationId);
|
||||||
|
response.setNote(null);
|
||||||
|
response.setStatus(ApplicationEvaluationStatusTypeEnum.valueOf(ApplicationEvaluationStatusTypeEnum.DRAFT.getValue()));
|
||||||
|
|
||||||
|
setCriteriaResponses(entity, applicationId, response, evaluationCriterias);
|
||||||
|
setChecklistResponses(entity, applicationId, response, checklistEntities);
|
||||||
|
setFileResponses(entity, applicationId, response, applicationFormEntities);
|
||||||
|
|
||||||
|
setApplicationDetails(response, applicationId, user);
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setCriteriaResponses(ApplicationEvaluationEntity entity, Long applicationId, ApplicationEvaluationResponse response, List<EvaluationCriteriaEntity> evaluationCriterias) {
|
||||||
|
List<CriteriaResponse> criteriaResponses = entity.getCriteria() != null
|
||||||
|
? Utils.convertJsonToList(entity.getCriteria(), new TypeReference<List<CriteriaResponse>>() {})
|
||||||
|
: getCriteriaResponse(applicationId);
|
||||||
|
|
||||||
|
criteriaResponses.forEach(criteriaResponse -> {
|
||||||
|
EvaluationCriteriaEntity matchingEvaluationCriteria = evaluationCriterias.stream()
|
||||||
|
.filter(evaluationCriteria -> evaluationCriteria.getId().equals(criteriaResponse.getId()))
|
||||||
|
.findFirst()
|
||||||
|
.orElse(null);
|
||||||
|
|
||||||
|
if (matchingEvaluationCriteria != null) {
|
||||||
|
criteriaResponse.setLabel(matchingEvaluationCriteria.getLookupData().getValue());
|
||||||
|
criteriaResponse.setMaxScore(matchingEvaluationCriteria.getScore());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
response.setCriteria(criteriaResponses);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setChecklistResponses(ApplicationEvaluationEntity entity, Long applicationId, ApplicationEvaluationResponse response, List<CallTargetAudienceChecklistEntity> checklistEntities) {
|
||||||
|
List<ChecklistResponse> checklistResponses = entity.getChecklist() != null
|
||||||
|
? Utils.convertJsonToList(entity.getChecklist(), new TypeReference<List<ChecklistResponse>>() {})
|
||||||
|
: getChecklistResponse(applicationId);
|
||||||
|
|
||||||
|
checklistResponses.forEach(checklistResponse -> {
|
||||||
|
CallTargetAudienceChecklistEntity matchingChecklist = checklistEntities.stream()
|
||||||
|
.filter(checklistEntity -> checklistEntity.getId().equals(checklistResponse.getId()))
|
||||||
|
.findFirst()
|
||||||
|
.orElse(null);
|
||||||
|
|
||||||
|
if (matchingChecklist != null) {
|
||||||
|
checklistResponse.setLabel(matchingChecklist.getLookupData().getValue());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
response.setChecklist(checklistResponses);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setFileResponses(ApplicationEvaluationEntity entity, Long applicationId, ApplicationEvaluationResponse response, List<ApplicationFormEntity> applicationFormEntities) {
|
||||||
|
List<FieldResponse> fieldResponses = entity.getFile() != null
|
||||||
|
? Utils.convertJsonToList(entity.getFile(), new TypeReference<List<FieldResponse>>() {})
|
||||||
|
: getFieldResponses(applicationId);
|
||||||
|
|
||||||
|
fieldResponses.forEach(fieldResponse -> {
|
||||||
|
applicationFormEntities.forEach(applicationForm -> {
|
||||||
|
FormEntity formEntity = applicationForm.getForm();
|
||||||
|
if (formEntity != null) {
|
||||||
|
List<ContentResponseBean> contentResponseBeans = Utils.convertJsonStringToList(formEntity.getContent(), ContentResponseBean.class);
|
||||||
|
contentResponseBeans.forEach(contentResponseBean -> {
|
||||||
|
if ("fileupload".equals(contentResponseBean.getName()) && contentResponseBean.getId().equals(fieldResponse.getId())) {
|
||||||
|
fieldResponse.setLabel(contentResponseBean.getLabel());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
response.setFiles(fieldResponses);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setApplicationDetails(ApplicationEvaluationResponse response, Long applicationId, UserEntity user) {
|
||||||
|
ApplicationEntity application = applicationService.validateApplication(applicationId);
|
||||||
|
userService.validateUser(application.getUserId());
|
||||||
|
String firstName = user.getFirstName() != null ? user.getFirstName() : "";
|
||||||
|
String lastName = user.getLastName() != null ? user.getLastName() : "";
|
||||||
|
|
||||||
|
String beneficiary = String.join(" ", firstName, lastName).trim();
|
||||||
|
response.setBeneficiary(beneficiary);
|
||||||
|
|
||||||
|
response.setCallName(application.getCall().getName());
|
||||||
|
response.setProtocolNumber(application.getProtocol() != null ? application.getProtocol().getProtocolNumber() : null);
|
||||||
|
response.setSubmissionDate(application.getSubmissionDate());
|
||||||
|
response.setEvaluationDate(LocalDateTime.now());
|
||||||
|
}
|
||||||
|
|
||||||
|
List<CriteriaResponse> getCriteriaResponse(Long applicationId){ CallEntity call = callRepository.findCallEntityByApplicationId(applicationId);
|
||||||
|
List<EvaluationCriteriaEntity> evaluationCriterias = evaluationCriteriaRepository.findByCallId(call.getId());
|
||||||
|
List<CriteriaResponse> criteriaResponses = evaluationCriterias.stream().map(criteria -> {
|
||||||
|
CriteriaResponse response = new CriteriaResponse();
|
||||||
|
response.setId(criteria.getId());
|
||||||
|
response.setLabel(criteria.getLookupData().getValue());
|
||||||
|
response.setScore(null);
|
||||||
|
response.setMaxScore(criteria.getScore());
|
||||||
|
response.setValid(null);
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}).collect(Collectors.toList());
|
||||||
|
|
||||||
|
return criteriaResponses;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<ChecklistResponse> getChecklistResponse(Long applicationId){ CallEntity call = callRepository.findCallEntityByApplicationId(applicationId);
|
||||||
|
List<CallTargetAudienceChecklistEntity> checklistEntities = callTargetAudienceChecklistRepository.findByCallId(call.getId());
|
||||||
|
List<ChecklistResponse> checklistResponses = checklistEntities.stream().map(checklist -> {
|
||||||
|
ChecklistResponse response = new ChecklistResponse();
|
||||||
|
response.setId(checklist.getId());
|
||||||
|
response.setLabel(checklist.getLookupData().getValue());
|
||||||
|
response.setValid(null);
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}).collect(Collectors.toList());
|
||||||
|
|
||||||
|
return checklistResponses;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<FieldResponse> getFieldResponses(Long applicationId) {
|
||||||
|
List<ApplicationFormEntity> applicationFormEntities = applicationFormRepository.findByApplicationId(applicationId);
|
||||||
|
List<FieldResponse> fieldResponses = new ArrayList<>();
|
||||||
|
|
||||||
|
for (ApplicationFormEntity applicationForm : applicationFormEntities) {
|
||||||
|
FormEntity formEntity = applicationForm.getForm();
|
||||||
|
|
||||||
|
if (formEntity != null) {
|
||||||
|
List<ContentResponseBean> contentResponseBeans = Utils.convertJsonStringToList(formEntity.getContent(), ContentResponseBean.class);
|
||||||
|
|
||||||
|
for (ContentResponseBean contentResponseBean : contentResponseBeans) {
|
||||||
|
if ("fileupload".equals(contentResponseBean.getName())) {
|
||||||
|
String fieldId = contentResponseBean.getId();
|
||||||
|
Long formId = applicationForm.getId();
|
||||||
|
|
||||||
|
Optional<ApplicationFormFieldEntity> optionalFormField = applicationFormFieldRepository
|
||||||
|
.findByFieldIdAndApplicationFormIdAndApplicationFormApplicationId(fieldId, formId, applicationId);
|
||||||
|
|
||||||
|
if (optionalFormField.isPresent()) {
|
||||||
|
ApplicationFormFieldEntity formField = optionalFormField.get();
|
||||||
|
|
||||||
|
if (formField.getFieldValue() != null) {
|
||||||
|
FieldResponse fieldResponse = new FieldResponse();
|
||||||
|
fieldResponse.setId(fieldId);
|
||||||
|
fieldResponse.setLabel(contentResponseBean.getLabel());
|
||||||
|
fieldResponse.setValid(null);
|
||||||
|
fieldResponses.add(fieldResponse);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return fieldResponses;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deleteById(Long id) {
|
||||||
|
ApplicationEvaluationEntity applicationEvaluationEntity= validateApplicationEvaluation(id);
|
||||||
|
applicationEvaluationEntity.setIsDeleted(true);
|
||||||
|
applicationEvaluationEntity=saveApplicationEvaluationEntity(applicationEvaluationEntity);
|
||||||
|
}
|
||||||
|
public ApplicationEvaluationEntity saveApplicationEvaluationEntity(ApplicationEvaluationEntity applicationEvaluationEntityData){
|
||||||
|
return applicationEvaluationRepository.save(applicationEvaluationEntityData);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ApplicationEvaluationResponse updateApplicationEvaluationStatus(Long applicationId, ApplicationEvaluationStatusTypeEnum status) {
|
||||||
|
ApplicationEvaluationEntity existingEntity = validateApplicationEvaluation(applicationId);
|
||||||
|
if (status != null && !status.getValue().equals(existingEntity.getStatus())) {
|
||||||
|
existingEntity.setStatus(status.getValue());
|
||||||
|
}
|
||||||
|
ApplicationEvaluationEntity updatedEntity = applicationEvaluationRepository.save(existingEntity);
|
||||||
|
return convertToResponse(updatedEntity);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
package net.gepafin.tendermanagement.entities;
|
||||||
|
|
||||||
|
import jakarta.persistence.*;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.List;
|
||||||
|
@Data
|
||||||
|
@Entity
|
||||||
|
@Table(name = "application_evaluation")
|
||||||
|
public class ApplicationEvaluationEntity extends BaseEntity{
|
||||||
|
|
||||||
|
@ManyToOne
|
||||||
|
@JoinColumn(name = "APPLICATION_ID", nullable = true)
|
||||||
|
private ApplicationEntity application;
|
||||||
|
@Column(name = "user_id")
|
||||||
|
private Long userId;
|
||||||
|
|
||||||
|
@Column(name = "criteria")
|
||||||
|
private String criteria;
|
||||||
|
|
||||||
|
@Column(name = "checklist")
|
||||||
|
private String checklist;
|
||||||
|
|
||||||
|
@Column(name = "file")
|
||||||
|
private String file;
|
||||||
|
@Column(name = "note")
|
||||||
|
private String note;
|
||||||
|
@Column(name = "status")
|
||||||
|
private String status;
|
||||||
|
|
||||||
|
@Column(name="IS_DELETED")
|
||||||
|
private Boolean isDeleted;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package net.gepafin.tendermanagement.enums;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonValue;
|
||||||
|
|
||||||
|
public enum ApplicationEvaluationStatusTypeEnum {
|
||||||
|
DRAFT("DRAFT"),
|
||||||
|
APPROVED("APPROVED"),
|
||||||
|
REJECTED("REJECTED");
|
||||||
|
|
||||||
|
private String value;
|
||||||
|
|
||||||
|
ApplicationEvaluationStatusTypeEnum(String value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonValue
|
||||||
|
public String getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package net.gepafin.tendermanagement.model.request;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import net.gepafin.tendermanagement.enums.ApplicationEvaluationStatusTypeEnum;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
@Data
|
||||||
|
public class ApplicationEvaluationRequest {
|
||||||
|
|
||||||
|
private Long applicationId;
|
||||||
|
private List<CriteriaRequest> criteria;
|
||||||
|
private List<ChecklistRequest> checklist;
|
||||||
|
private List<FieldRequest> field;
|
||||||
|
private String note;
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package net.gepafin.tendermanagement.model.request;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class ChecklistRequest {
|
||||||
|
private Long id;
|
||||||
|
private Boolean valid;
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package net.gepafin.tendermanagement.model.request;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class CriteriaRequest {
|
||||||
|
private Long id;
|
||||||
|
private Long score;
|
||||||
|
private Boolean valid;
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package net.gepafin.tendermanagement.model.request;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class FieldRequest {
|
||||||
|
private String id;
|
||||||
|
private Boolean valid;
|
||||||
|
}
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
package net.gepafin.tendermanagement.model.request;public class UpdateApplicationEvaluationRequest {
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package net.gepafin.tendermanagement.model.response;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import net.gepafin.tendermanagement.enums.ApplicationEvaluationStatusTypeEnum;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class ApplicationEvaluationResponse {
|
||||||
|
|
||||||
|
|
||||||
|
private Long id;
|
||||||
|
private Long applicationId;
|
||||||
|
private String note;
|
||||||
|
private ApplicationEvaluationStatusTypeEnum status;
|
||||||
|
private List<CriteriaResponse> criteria;
|
||||||
|
private List<ChecklistResponse> checklist;
|
||||||
|
private List<FieldResponse> files;
|
||||||
|
private LocalDateTime createdDate;
|
||||||
|
private LocalDateTime updatedDate;
|
||||||
|
private String beneficiary;
|
||||||
|
private Long protocolNumber;
|
||||||
|
private String callName;
|
||||||
|
private LocalDateTime submissionDate;
|
||||||
|
private LocalDateTime evaluationDate;
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package net.gepafin.tendermanagement.model.response;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class ChecklistResponse {
|
||||||
|
private Long id;
|
||||||
|
private String label;
|
||||||
|
private Boolean valid;
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package net.gepafin.tendermanagement.model.response;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class CriteriaResponse {
|
||||||
|
private Long id;
|
||||||
|
private String label;
|
||||||
|
private Long score;
|
||||||
|
private Long maxScore;
|
||||||
|
private Boolean valid;
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package net.gepafin.tendermanagement.model.response;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class FieldResponse {
|
||||||
|
private String id;
|
||||||
|
private String label;
|
||||||
|
private Boolean valid;
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package net.gepafin.tendermanagement.repositories;
|
||||||
|
|
||||||
|
import net.gepafin.tendermanagement.entities.ApplicationEvaluationEntity;
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
@Repository
|
||||||
|
public interface ApplicationEvaluationRepository extends JpaRepository<ApplicationEvaluationEntity, Long> {
|
||||||
|
Optional<ApplicationEvaluationEntity> findByApplicationId(Long applicationId);
|
||||||
|
|
||||||
|
}
|
||||||
@@ -23,5 +23,16 @@ public interface ApplicationFormFieldRepository extends JpaRepository<Applicatio
|
|||||||
|
|
||||||
public List<ApplicationFormFieldEntity> findByFieldValueInAndApplicationFormApplicationId(
|
public List<ApplicationFormFieldEntity> findByFieldValueInAndApplicationFormApplicationId(
|
||||||
List<String> fieldValue, Long applicationId);
|
List<String> fieldValue, Long applicationId);
|
||||||
|
/**
|
||||||
|
* Find ApplicationFormField entity by Field ID, Form ID, and Application ID.
|
||||||
|
*
|
||||||
|
* @param fieldId The Field ID to search.
|
||||||
|
* @param formId The Form ID to search.
|
||||||
|
* @param applicationId The Application ID to search.
|
||||||
|
* @return Optional of ApplicationFormFieldEntity
|
||||||
|
*/
|
||||||
|
Optional<ApplicationFormFieldEntity> findByFieldIdAndApplicationFormIdAndApplicationFormApplicationId(
|
||||||
|
String fieldId, Long formId, Long applicationId);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,4 +25,8 @@ public interface CallRepository extends JpaRepository<CallEntity, Long> {
|
|||||||
"FROM CallEntity c LEFT JOIN ApplicationEntity a ON c.id = a.call.id " +
|
"FROM CallEntity c LEFT JOIN ApplicationEntity a ON c.id = a.call.id " +
|
||||||
"GROUP BY c.name")
|
"GROUP BY c.name")
|
||||||
List<Object[]> findApplicationsPerCall();
|
List<Object[]> findApplicationsPerCall();
|
||||||
|
|
||||||
|
|
||||||
|
@Query("SELECT c FROM CallEntity c JOIN ApplicationEntity a ON c.id = a.call.id WHERE a.id = :applicationId")
|
||||||
|
CallEntity findCallEntityByApplicationId(Long applicationId);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,4 +17,5 @@ public interface CallTargetAudienceChecklistRepository extends JpaRepository<Cal
|
|||||||
Optional<CallTargetAudienceChecklistEntity> findById(@Param("id") Long id);
|
Optional<CallTargetAudienceChecklistEntity> findById(@Param("id") Long id);
|
||||||
|
|
||||||
List<CallTargetAudienceChecklistEntity> findByCallIdAndLookupDataTypeAndIsDeletedFalse(Long id, String type);
|
List<CallTargetAudienceChecklistEntity> findByCallIdAndLookupDataTypeAndIsDeletedFalse(Long id, String type);
|
||||||
|
List<CallTargetAudienceChecklistEntity> findByCallId(Long callId);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,4 +16,6 @@ public interface EvaluationCriteriaRepository extends JpaRepository<EvaluationCr
|
|||||||
Optional<EvaluationCriteriaEntity> findById(@Param("id") Long id);
|
Optional<EvaluationCriteriaEntity> findById(@Param("id") Long id);
|
||||||
|
|
||||||
List<EvaluationCriteriaEntity> findByCallIdAndLookupDataTypeAndIsDeletedFalse(Long callId, String type);
|
List<EvaluationCriteriaEntity> findByCallIdAndLookupDataTypeAndIsDeletedFalse(Long callId, String type);
|
||||||
|
List<EvaluationCriteriaEntity> findByCallId(Long callId);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package net.gepafin.tendermanagement.service;
|
||||||
|
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import net.gepafin.tendermanagement.enums.ApplicationEvaluationStatusTypeEnum;
|
||||||
|
import net.gepafin.tendermanagement.enums.ApplicationStatusTypeEnum;
|
||||||
|
import net.gepafin.tendermanagement.model.request.ApplicationEvaluationRequest;
|
||||||
|
import net.gepafin.tendermanagement.model.request.UpdateApplicationEvaluationRequest;
|
||||||
|
import net.gepafin.tendermanagement.model.response.ApplicationEvaluationResponse;
|
||||||
|
import net.gepafin.tendermanagement.model.response.ApplicationResponse;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface ApplicationEvaluationService {
|
||||||
|
ApplicationEvaluationResponse createOrUpdateApplicationEvaluation(HttpServletRequest request, ApplicationEvaluationRequest applicationEvaluationRequest);
|
||||||
|
void deleteApplicationEvaluation(HttpServletRequest request,Long id);
|
||||||
|
|
||||||
|
ApplicationEvaluationResponse getApplicationEvaluationByApplicationId(HttpServletRequest request,Long applicationId);
|
||||||
|
|
||||||
|
ApplicationEvaluationResponse updateApplicationEvaluationStatus(HttpServletRequest request, Long applicationEvaluationId, ApplicationEvaluationStatusTypeEnum status);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
package net.gepafin.tendermanagement.service.impl;
|
||||||
|
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import net.gepafin.tendermanagement.dao.ApplicationEvaluationDao;
|
||||||
|
|
||||||
|
import net.gepafin.tendermanagement.entities.UserEntity;
|
||||||
|
import net.gepafin.tendermanagement.enums.ApplicationEvaluationStatusTypeEnum;
|
||||||
|
import net.gepafin.tendermanagement.enums.ApplicationStatusTypeEnum;
|
||||||
|
import net.gepafin.tendermanagement.model.request.ApplicationEvaluationRequest;
|
||||||
|
import net.gepafin.tendermanagement.model.request.UpdateApplicationEvaluationRequest;
|
||||||
|
import net.gepafin.tendermanagement.model.response.ApplicationEvaluationResponse;
|
||||||
|
import net.gepafin.tendermanagement.model.response.ApplicationResponse;
|
||||||
|
import net.gepafin.tendermanagement.service.ApplicationEvaluationService;
|
||||||
|
import net.gepafin.tendermanagement.util.Validator;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class ApplicationEvaluationServiceImpl implements ApplicationEvaluationService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ApplicationEvaluationDao applicationEvaluationDao;
|
||||||
|
@Autowired
|
||||||
|
private Validator validator;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public ApplicationEvaluationResponse createOrUpdateApplicationEvaluation(HttpServletRequest request, ApplicationEvaluationRequest req) {
|
||||||
|
Long userId = validator.getUserIdFromToken(request);
|
||||||
|
UserEntity user=validator.validatePreInstructor(request,userId);
|
||||||
|
return applicationEvaluationDao.createOrUpdateApplicationEvaluation(user,req);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(readOnly = true)
|
||||||
|
public ApplicationEvaluationResponse getApplicationEvaluationByApplicationId(HttpServletRequest request,Long applicationId) {
|
||||||
|
Long userId = validator.getUserIdFromToken(request);
|
||||||
|
UserEntity user=validator.validatePreInstructor(request,userId);
|
||||||
|
return applicationEvaluationDao.getApplicationEvaluationByApplicationId(user,applicationId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public void deleteApplicationEvaluation(HttpServletRequest request,Long id) {
|
||||||
|
Long userId = validator.getUserIdFromToken(request);
|
||||||
|
applicationEvaluationDao.deleteById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public ApplicationEvaluationResponse updateApplicationEvaluationStatus(HttpServletRequest request, Long applicationId, ApplicationEvaluationStatusTypeEnum status) {
|
||||||
|
Long userId = validator.getUserIdFromToken(request);
|
||||||
|
validator.validatePreInstructor(request,userId);
|
||||||
|
return applicationEvaluationDao.updateApplicationEvaluationStatus(applicationId, status);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
package net.gepafin.tendermanagement.util;
|
package net.gepafin.tendermanagement.util;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
@@ -308,4 +309,23 @@ public class Utils {
|
|||||||
|
|
||||||
return new StringTokenizer(header, ",").nextToken().trim();
|
return new StringTokenizer(header, ",").nextToken().trim();
|
||||||
}
|
}
|
||||||
|
public static <T> List<T> convertJsonToList(String json, TypeReference<List<T>> typeRef) {
|
||||||
|
ObjectMapper objectMapper = new ObjectMapper();
|
||||||
|
try {
|
||||||
|
return objectMapper.readValue(json, typeRef);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String convertObjectToJson(Object obj) {
|
||||||
|
try {
|
||||||
|
return new ObjectMapper().writeValueAsString(obj);
|
||||||
|
} catch (JsonProcessingException e) {
|
||||||
|
log.error("Failed to convert object to JSON: {}", e.getMessage(), e);
|
||||||
|
throw new RuntimeException("Failed to convert object to JSON", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -95,9 +95,15 @@ public class Validator {
|
|||||||
return userService.validateUser(userId);
|
return userService.validateUser(userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Long getUserIdFromToken(HttpServletRequest request) {
|
public Long getUserIdFromToken(HttpServletRequest request) {
|
||||||
Map<String, Object> userInfo= tokenProvider.getUserInfoAndUserIdFromToken(request);
|
Map<String, Object> userInfo= tokenProvider.getUserInfoAndUserIdFromToken(request);
|
||||||
return Long.parseLong(userInfo.get("userId").toString());
|
return Long.parseLong(userInfo.get("userId").toString());
|
||||||
}
|
}
|
||||||
|
public UserEntity validatePreInstructor(HttpServletRequest request, Long userId) {
|
||||||
|
UserEntity user = validateUser(request);
|
||||||
|
if(Boolean.FALSE.equals(RoleStatusEnum.ROLE_PRE_INSTRUCTOR.getValue().equals(user.getRoleEntity().getRoleType()))||Boolean.FALSE.equals(user.getId().equals(userId))) {
|
||||||
|
throw new ForbiddenAccessException(Status.FORBIDDEN, Translator.toLocale(GepafinConstant.PERMISSION_DENIED));
|
||||||
|
}
|
||||||
|
return userService.validateUser(userId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,73 @@
|
|||||||
|
package net.gepafin.tendermanagement.web.rest.api;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Content;
|
||||||
|
import io.swagger.v3.oas.annotations.media.ExampleObject;
|
||||||
|
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import jakarta.validation.Valid;
|
||||||
|
import net.gepafin.tendermanagement.enums.ApplicationEvaluationStatusTypeEnum;
|
||||||
|
import net.gepafin.tendermanagement.enums.ApplicationStatusTypeEnum;
|
||||||
|
import net.gepafin.tendermanagement.model.request.ApplicationEvaluationRequest;
|
||||||
|
import net.gepafin.tendermanagement.model.request.UpdateApplicationEvaluationRequest;
|
||||||
|
import net.gepafin.tendermanagement.model.response.ApplicationEvaluationResponse;
|
||||||
|
import net.gepafin.tendermanagement.model.response.ApplicationResponse;
|
||||||
|
import net.gepafin.tendermanagement.model.util.Response;
|
||||||
|
import net.gepafin.tendermanagement.web.rest.api.errors.ErrorConstants;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface ApplicationEvaluationApi {
|
||||||
|
|
||||||
|
@Operation(summary = "API to create ApplicationEvaluation",
|
||||||
|
responses = {
|
||||||
|
@ApiResponse(responseCode = "200", description = "OK"),
|
||||||
|
@ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
|
||||||
|
@ExampleObject(value = ErrorConstants.NOTFOUND_ERROR_EXAMPLE) })),
|
||||||
|
@ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
|
||||||
|
@ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) }))
|
||||||
|
})
|
||||||
|
@PostMapping(value = "/", produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE)
|
||||||
|
ResponseEntity<Response<ApplicationEvaluationResponse>> createOrUpdateApplicationEvaluation(HttpServletRequest request,
|
||||||
|
@Parameter(description = "ApplicationEvaluation request object", required = true) @Valid @RequestBody ApplicationEvaluationRequest evaluationRequest);
|
||||||
|
|
||||||
|
@Operation(summary = "API to get ApplicationEvaluation data for evaluation process",
|
||||||
|
responses = {
|
||||||
|
@ApiResponse(responseCode = "200", description = "OK"),
|
||||||
|
@ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
|
||||||
|
@ExampleObject(value = ErrorConstants.NOTFOUND_ERROR_EXAMPLE) }))
|
||||||
|
})
|
||||||
|
@GetMapping(value = "/application/{applicationId}", produces = MediaType.APPLICATION_JSON_VALUE)
|
||||||
|
ResponseEntity<Response<ApplicationEvaluationResponse>> getApplicationEvaluationByApplicationId(HttpServletRequest request,
|
||||||
|
@Parameter(required = true) @PathVariable("applicationId") Long applicationId);
|
||||||
|
|
||||||
|
@Operation(summary = "API to delete ApplicationEvaluation",
|
||||||
|
responses = {
|
||||||
|
@ApiResponse(responseCode = "200", description = "OK"),
|
||||||
|
@ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
|
||||||
|
@ExampleObject(value = ErrorConstants.NOTFOUND_ERROR_EXAMPLE) }))
|
||||||
|
})
|
||||||
|
@DeleteMapping(value = "/{id}")
|
||||||
|
ResponseEntity<Response<Void>> deleteApplicationEvaluation(HttpServletRequest request,
|
||||||
|
@Parameter(description = "The evaluation ID", required = true) @PathVariable("id") Long id);
|
||||||
|
|
||||||
|
@Operation(summary = "Api to update application evaluation status",
|
||||||
|
responses = {
|
||||||
|
@ApiResponse(responseCode = "200", description = "OK"),
|
||||||
|
@ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
|
||||||
|
@ExampleObject(value = ErrorConstants.NOTFOUND_ERROR_EXAMPLE) })),
|
||||||
|
@ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
|
||||||
|
@ExampleObject(value = ErrorConstants.UNAUTHORIZED_ERROR_EXAMPLE) })),
|
||||||
|
@ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
|
||||||
|
@ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) })
|
||||||
|
@PutMapping(value = "/{id}/status", produces = MediaType.APPLICATION_JSON_VALUE)
|
||||||
|
ResponseEntity<Response<ApplicationEvaluationResponse>> updateApplicationEvaluationStatus(HttpServletRequest request,
|
||||||
|
@Parameter(description = "The evaluation ID", required = true) @PathVariable("id") Long id,
|
||||||
|
@Parameter(description = "status", required = true)@RequestParam(value = "status", required = true) ApplicationEvaluationStatusTypeEnum status);
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
package net.gepafin.tendermanagement.web.rest.api.impl;
|
||||||
|
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import net.gepafin.tendermanagement.config.Translator;
|
||||||
|
import net.gepafin.tendermanagement.constants.GepafinConstant;
|
||||||
|
import net.gepafin.tendermanagement.enums.ApplicationEvaluationStatusTypeEnum;
|
||||||
|
import net.gepafin.tendermanagement.enums.ApplicationStatusTypeEnum;
|
||||||
|
import net.gepafin.tendermanagement.model.request.ApplicationEvaluationRequest;
|
||||||
|
import net.gepafin.tendermanagement.model.request.UpdateApplicationEvaluationRequest;
|
||||||
|
import net.gepafin.tendermanagement.model.response.ApplicationEvaluationResponse;
|
||||||
|
import net.gepafin.tendermanagement.model.response.ApplicationResponse;
|
||||||
|
import net.gepafin.tendermanagement.model.util.Response;
|
||||||
|
import net.gepafin.tendermanagement.service.ApplicationEvaluationService;
|
||||||
|
import net.gepafin.tendermanagement.web.rest.api.ApplicationEvaluationApi;
|
||||||
|
import net.gepafin.tendermanagement.web.rest.api.errors.Status;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("${openapi.gepafin.base-path:/v1/applicationEvaluation}")
|
||||||
|
public class ApplicationEvaluationApiController implements ApplicationEvaluationApi {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ApplicationEvaluationService applicationEvaluationService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResponseEntity<Response<ApplicationEvaluationResponse>> createOrUpdateApplicationEvaluation(HttpServletRequest request,
|
||||||
|
ApplicationEvaluationRequest evaluationRequest) {
|
||||||
|
ApplicationEvaluationResponse response = applicationEvaluationService.createOrUpdateApplicationEvaluation(request,evaluationRequest);
|
||||||
|
return ResponseEntity.status(HttpStatus.CREATED)
|
||||||
|
.body(new Response<>(response, Status.SUCCESS, Translator.toLocale(GepafinConstant.EVALUATION_CREATED_SUCCESSFULLY)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResponseEntity<Response<ApplicationEvaluationResponse>> getApplicationEvaluationByApplicationId(HttpServletRequest request,
|
||||||
|
Long applicationId) {
|
||||||
|
ApplicationEvaluationResponse response = applicationEvaluationService.getApplicationEvaluationByApplicationId(request,applicationId);
|
||||||
|
return ResponseEntity.status(HttpStatus.OK)
|
||||||
|
.body(new Response<>(response, Status.SUCCESS, Translator.toLocale(GepafinConstant.EVALUATION_FETCHED_SUCCESSFULLY)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResponseEntity<Response<Void>> deleteApplicationEvaluation(HttpServletRequest request,
|
||||||
|
Long id) {
|
||||||
|
applicationEvaluationService.deleteApplicationEvaluation(request,id);
|
||||||
|
return ResponseEntity.status(HttpStatus.OK)
|
||||||
|
.body(new Response<>(null, Status.SUCCESS, Translator.toLocale(GepafinConstant.EVALUATION_DELETED_SUCCESSFULLY)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResponseEntity<Response<ApplicationEvaluationResponse>> updateApplicationEvaluationStatus(HttpServletRequest request, Long applicationId,
|
||||||
|
ApplicationEvaluationStatusTypeEnum status) {
|
||||||
|
ApplicationEvaluationResponse applicationEvaluationResponse = applicationEvaluationService.updateApplicationEvaluationStatus(request, applicationId, status);
|
||||||
|
return ResponseEntity.status(HttpStatus.OK)
|
||||||
|
.body(new Response<>(applicationEvaluationResponse, Status.SUCCESS, Translator.toLocale(GepafinConstant.APPLICATION_EVALUATION_STATUS_UPDATED_SUCCESSFULLY)));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1108,4 +1108,58 @@
|
|||||||
</column>
|
</column>
|
||||||
</addColumn>
|
</addColumn>
|
||||||
</changeSet>
|
</changeSet>
|
||||||
|
|
||||||
|
|
||||||
|
<changeSet id="26-10-2024_1" author="Harish Bagora">
|
||||||
|
<createTable tableName="application_evaluation">
|
||||||
|
<column autoIncrement="true" name="id" type="INTEGER">
|
||||||
|
<constraints nullable="false" primaryKey="true" primaryKeyName="application_evaluation_pkey"/>
|
||||||
|
</column>
|
||||||
|
<column name="application_id" type="INTEGER">
|
||||||
|
<constraints nullable="false"/>
|
||||||
|
</column>
|
||||||
|
<column name="user_id" type="INTEGER">
|
||||||
|
<constraints nullable="false"/>
|
||||||
|
</column>
|
||||||
|
<column name="criteria" type="TEXT">
|
||||||
|
<constraints nullable="true"/>
|
||||||
|
</column>
|
||||||
|
<column name="checklist" type="TEXT">
|
||||||
|
<constraints nullable="true"/>
|
||||||
|
</column>
|
||||||
|
<column name="file" type="TEXT">
|
||||||
|
<constraints nullable="true"/>
|
||||||
|
</column>
|
||||||
|
<column name="note" type="TEXT">
|
||||||
|
<constraints nullable="true"/>
|
||||||
|
</column>
|
||||||
|
<column name="status" type="VARCHAR(255)">
|
||||||
|
<constraints nullable="false"/>
|
||||||
|
</column>
|
||||||
|
<column name="created_date" type="TIMESTAMP WITHOUT TIME ZONE">
|
||||||
|
<constraints nullable="true"/>
|
||||||
|
</column>
|
||||||
|
<column name="updated_date" type="TIMESTAMP WITHOUT TIME ZONE">
|
||||||
|
<constraints nullable="true"/>
|
||||||
|
</column>
|
||||||
|
<column name="is_deleted" type="BOOLEAN" defaultValueBoolean="false">
|
||||||
|
<constraints nullable="false"/>
|
||||||
|
</column>
|
||||||
|
</createTable>
|
||||||
|
|
||||||
|
<addForeignKeyConstraint
|
||||||
|
baseTableName="application_evaluation"
|
||||||
|
baseColumnNames="user_id"
|
||||||
|
referencedTableName="gepafin_user"
|
||||||
|
referencedColumnNames="id"
|
||||||
|
constraintName="fk_application_evaluation_gepafin_user"
|
||||||
|
onDelete="CASCADE" />
|
||||||
|
<addForeignKeyConstraint
|
||||||
|
baseTableName="application_evaluation"
|
||||||
|
baseColumnNames="application_id"
|
||||||
|
referencedTableName="application"
|
||||||
|
referencedColumnNames="id"
|
||||||
|
constraintName="fk_application_evaluation_application"
|
||||||
|
onDelete="CASCADE" />
|
||||||
|
</changeSet>
|
||||||
</databaseChangeLog>
|
</databaseChangeLog>
|
||||||
|
|||||||
@@ -253,6 +253,13 @@ get_login_attempt_se_msg=Login attempts fetched successfully.
|
|||||||
application.in.submit.status.cannot.delete.company=The company cannot be deleted because there are active applications in the SUBMITTED status.
|
application.in.submit.status.cannot.delete.company=The company cannot be deleted because there are active applications in the SUBMITTED status.
|
||||||
get.users.success.msg = Successfully fetched users.
|
get.users.success.msg = Successfully fetched users.
|
||||||
cannot.create.beneficiary.user = Creation of a Beneficiary user is not allowed. Please assign the appropriate role.
|
cannot.create.beneficiary.user = Creation of a Beneficiary user is not allowed. Please assign the appropriate role.
|
||||||
|
application.evaluation.not.found=Application Evaluation not found with ID: {0}
|
||||||
|
evaluation.created.successfully = Application evaluation created successfully.
|
||||||
|
evaluation.updated.successfully = Application evaluation updated successfully.
|
||||||
|
evaluation.fetched.successfully = Application evaluation fetched successfully.
|
||||||
|
evaluation.deleted.successfully = Application evaluation deleted successfully.
|
||||||
|
evaluations.fetched.successfully = All application evaluations fetched successfully.
|
||||||
|
application.evaluation.status.updated.successfully=Application evaluation status updated successfully.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -251,3 +251,10 @@ application.in.submit.status.cannot.delete.company=Non
|
|||||||
get.users.success.msg = Utenti recuperati con successo
|
get.users.success.msg = Utenti recuperati con successo
|
||||||
cannot.create.beneficiary.user = La creazione di un utente beneficiario non è consentita. Si prega di assegnare il ruolo appropriato.
|
cannot.create.beneficiary.user = La creazione di un utente beneficiario non è consentita. Si prega di assegnare il ruolo appropriato.
|
||||||
|
|
||||||
|
application.evaluation.not.found=Valutazione dell'applicazione non trovata con ID: {0}
|
||||||
|
evaluation.created.successfully = Valutazione dell'applicazione creata con successo.
|
||||||
|
evaluation.updated.successfully = Valutazione dell'applicazione aggiornata con successo.
|
||||||
|
evaluation.fetched.successfully = Valutazione dell'applicazione recuperata con successo.
|
||||||
|
evaluation.deleted.successfully = Valutazione dell'applicazione eliminata con successo.
|
||||||
|
evaluations.fetched.successfully = Tutte le valutazioni delle applicazioni recuperate con successo.
|
||||||
|
application.evaluation.status.updated.successfully=Stato della valutazione dell'applicazione aggiornato con successo.
|
||||||
|
|||||||
Reference in New Issue
Block a user