1529 lines
74 KiB
Java
1529 lines
74 KiB
Java
package net.gepafin.tendermanagement.dao;
|
|
|
|
import java.io.ByteArrayOutputStream;
|
|
import java.io.IOException;
|
|
import java.io.InputStream;
|
|
import java.math.BigDecimal;
|
|
import java.sql.Timestamp;
|
|
import java.time.LocalDate;
|
|
import java.time.LocalDateTime;
|
|
import java.time.LocalTime;
|
|
import java.time.OffsetDateTime;
|
|
import java.time.format.DateTimeFormatter;
|
|
import java.util.*;
|
|
import java.util.stream.Collectors;
|
|
import java.util.zip.ZipEntry;
|
|
import java.util.zip.ZipOutputStream;
|
|
|
|
import jakarta.persistence.criteria.CriteriaBuilder;
|
|
import jakarta.persistence.criteria.Expression;
|
|
import jakarta.persistence.criteria.Predicate;
|
|
import jakarta.persistence.criteria.Root;
|
|
import jakarta.persistence.criteria.*;
|
|
import jakarta.servlet.http.HttpServletRequest;
|
|
import net.gepafin.tendermanagement.entities.*;
|
|
import net.gepafin.tendermanagement.enums.*;
|
|
import net.gepafin.tendermanagement.model.request.*;
|
|
import net.gepafin.tendermanagement.model.response.*;
|
|
import net.gepafin.tendermanagement.model.util.SortBy;
|
|
import net.gepafin.tendermanagement.repositories.*;
|
|
import net.gepafin.tendermanagement.service.*;
|
|
import net.gepafin.tendermanagement.util.DateTimeUtil;
|
|
import net.gepafin.tendermanagement.util.LoggingUtil;
|
|
import net.gepafin.tendermanagement.util.Utils;
|
|
import net.gepafin.tendermanagement.util.Validator;
|
|
import org.h2.util.IOUtils;
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
import org.springframework.data.domain.Page;
|
|
import org.springframework.data.domain.PageRequest;
|
|
import org.springframework.data.jpa.domain.Specification;
|
|
import org.springframework.stereotype.Component;
|
|
import org.springframework.util.CollectionUtils;
|
|
import org.springframework.util.StringUtils;
|
|
|
|
import net.gepafin.tendermanagement.config.Translator;
|
|
import net.gepafin.tendermanagement.constants.GepafinConstant;
|
|
import net.gepafin.tendermanagement.entities.LookUpDataEntity.LookUpDataTypeEnum;
|
|
import net.gepafin.tendermanagement.service.impl.CallValidatorServiceImpl;
|
|
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 static net.gepafin.tendermanagement.enums.RoleStatusEnum.ROLE_SUPER_ADMIN;
|
|
import static net.gepafin.tendermanagement.util.Utils.log;
|
|
import static net.gepafin.tendermanagement.util.Utils.setIfUpdated;
|
|
import static org.apache.commons.lang3.StringUtils.isEmpty;
|
|
import static org.hibernate.internal.util.collections.CollectionHelper.listOf;
|
|
|
|
@Component
|
|
public class CallDao {
|
|
|
|
@Autowired
|
|
private CallRepository callRepository;
|
|
|
|
@Autowired
|
|
private DocumentRepository documentRepository;
|
|
|
|
@Autowired
|
|
private EvaluationCriteriaRepository evaluationCriteriaRepository;
|
|
|
|
@Autowired
|
|
private FaqRepository faqRepository;
|
|
|
|
@Autowired
|
|
private RegionRepository regionRepository;
|
|
|
|
@Autowired
|
|
private LookUpDataService lookUpDataService;
|
|
|
|
@Autowired
|
|
private CallTargetAudienceChecklistRepository callTargetAudienceChecklistRepository;
|
|
|
|
@Autowired
|
|
private FaqService faqService;
|
|
|
|
@Autowired
|
|
private FlowDao flowDao;
|
|
|
|
@Autowired
|
|
private FormDao formDao;
|
|
|
|
// @Value("${aws.s3.url.folder}")
|
|
// private String s3Folder;
|
|
|
|
@Autowired
|
|
private AmazonS3Service amazonS3Service;
|
|
|
|
@Autowired
|
|
private CriteriaFormFieldRepository criteriaFormFieldRepository;
|
|
|
|
@Autowired
|
|
private S3PathConfig s3PathConfig;
|
|
@Autowired
|
|
private BeneficiaryPreferredCallRepository beneficiaryPreferredCallRepository;
|
|
@Autowired
|
|
private Validator validator;
|
|
|
|
@Autowired
|
|
private CompanyService companyService;
|
|
|
|
@Autowired
|
|
private LoggingUtil loggingUtil;
|
|
|
|
@Autowired
|
|
private HttpServletRequest request;
|
|
|
|
@Autowired
|
|
private NotificationDao notificationDao;
|
|
|
|
@Autowired
|
|
private BeneficiaryRepository beneficiaryRepository;
|
|
|
|
@Autowired
|
|
private NotificationTypeRepository notificationTypeRepository;
|
|
|
|
@Autowired
|
|
private EvaluationFormDao evalualtionFormDao;
|
|
|
|
@Autowired
|
|
private ApplicationRepository applicationRepository;
|
|
|
|
public CallResponse createCallStep1(CreateCallRequestStep1 createCallRequest, UserEntity userEntity) {
|
|
log.info("Starting Call creation - Step 1 by userId: {}", userEntity.getId());
|
|
createCallRequest.setRegionId(userEntity.getRoleEntity().getRegion().getId());
|
|
CallEntity callEntity = convertToCallEntity(createCallRequest, userEntity);
|
|
|
|
updateFaq(createCallRequest.getFaq(), callEntity, userEntity,LookUpDataTypeEnum.FAQ);
|
|
updateLookUpData(callEntity, createCallRequest.getAimedTo(), LookUpDataTypeEnum.AIMED_TO);
|
|
|
|
CallResponse createCallResponseBean = getCallResponseBean(callEntity);
|
|
createCallResponseBean.setCurrentStep(GepafinConstant.STEP_1);
|
|
log.info("Call creation - Step 1 completed successfully for callId: {}", callEntity.getId());
|
|
return createCallResponseBean;
|
|
|
|
}
|
|
public byte[] downloadCallDocumentsAsZip(Long callId) {
|
|
log.info("Starting download of call documents as ZIP for callId: {}", callId);
|
|
List<DocumentEntity> documents = documentRepository.findBySourceIdAndSourceAndTypeAndIsDeletedFalse(callId, DocumentSourceTypeEnum.CALL.getValue(),DocumentTypeEnum.DOCUMENT.getValue());
|
|
if (documents.isEmpty()) {
|
|
log.warn("No documents found for callId: {}", callId);
|
|
throw new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.DOCUMENT_NOT_FOUND));
|
|
}
|
|
|
|
try (ByteArrayOutputStream zipOutputStream = new ByteArrayOutputStream();
|
|
ZipOutputStream zos = new ZipOutputStream(zipOutputStream)) {
|
|
|
|
for (DocumentEntity document : documents) {
|
|
log.info("Adding document to ZIP: documentId={}, fileName={}", document.getId(), document.getFileName());
|
|
String s3Folder = s3PathConfig.generateDocumentPath(DocumentSourceTypeEnum.CALL, callId, 0L,0L,0L,0L);
|
|
try (InputStream fileInputStream = amazonS3Service.getFile(s3Folder, document.getFilePath())) {
|
|
String fileName = Utils.extractFileName(document.getFilePath());
|
|
ZipEntry zipEntry = new ZipEntry(fileName);
|
|
zos.putNextEntry(zipEntry);
|
|
IOUtils.copy(fileInputStream, zos);
|
|
zos.closeEntry();
|
|
} catch (IOException e) {
|
|
log.error("Error downloading or adding document to ZIP. documentId={}, fileName={}", document.getId(), document.getFileName(), e);
|
|
throw new RuntimeException("Error downloading or adding document to ZIP: " + document.getFileName(), e);
|
|
}
|
|
}
|
|
|
|
zos.finish();
|
|
log.info("Successfully created ZIP file for callId: {}", callId);
|
|
return zipOutputStream.toByteArray();
|
|
|
|
} catch (IOException e) {
|
|
log.error("Error while creating ZIP file for callId: {}", callId, e);
|
|
throw new RuntimeException("Error while creating ZIP file", e);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
public CallEntity convertToCallEntity(CreateCallRequestStep1 createCallRequest, UserEntity userEntity) {
|
|
CallEntity callEntity = new CallEntity();
|
|
// validateCallEntity(createCallRequest);
|
|
RegionEntity region = regionRepository.findById(createCallRequest.getRegionId())
|
|
.orElseThrow(() -> {
|
|
log.error("Region not found for id: {}", createCallRequest.getRegionId());
|
|
return new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.REGION_NOT_FOUND));
|
|
});
|
|
|
|
callEntity.setRegion(region);
|
|
callEntity.setName(createCallRequest.getName());
|
|
callEntity.setDescriptionShort(createCallRequest.getDescriptionShort());
|
|
callEntity.setDescriptionLong(createCallRequest.getDescriptionLong());
|
|
List<LocalDateTime> dates = createCallRequest.getDates();
|
|
if(dates!=null) {
|
|
if(dates.size()>1) {
|
|
callEntity.setStartDate(dates.get(0));
|
|
callEntity.setEndDate(dates.get(1));
|
|
}
|
|
}
|
|
callEntity.setStatus(CallStatusEnum.DRAFT.getValue());
|
|
callEntity.setEvaluationVersion(createCallRequest.getEvaluationVersion().getValue());
|
|
callEntity.setAmountMax(createCallRequest.getAmountMax());
|
|
callEntity.setAmount(createCallRequest.getAmount());
|
|
callEntity.setConfidi(false);
|
|
if (createCallRequest.getConfidi() != null) {
|
|
callEntity.setConfidi(createCallRequest.getConfidi());
|
|
}
|
|
callEntity.setDocumentationRequested(createCallRequest.getDocumentationRequested());
|
|
if (createCallRequest.getAmountMin() != null && createCallRequest.getAmountMin().compareTo(BigDecimal.ZERO) < 0) {
|
|
log.error("Invalid minimum amount: {}", createCallRequest.getAmountMin());
|
|
throw new CustomValidationException(Status.VALIDATION_ERROR,Translator.toLocale(GepafinConstant.AMOUNT_GREATER_THAN_ZERO_MSG));
|
|
}
|
|
callEntity.setAmountMin(createCallRequest.getAmountMin());
|
|
if(createCallRequest.getEmail()!=null && Boolean.FALSE.equals(Utils.isValidEmail(createCallRequest.getEmail()))){
|
|
throw new CustomValidationException(Status.VALIDATION_ERROR,Translator.toLocale(GepafinConstant.VALIDATION_EMAIL,createCallRequest.getEmail()));
|
|
}
|
|
callEntity.setEmail(createCallRequest.getEmail());
|
|
callEntity.setPhoneNumber(createCallRequest.getPhoneNumber());
|
|
callEntity.setStartTime(DateTimeUtil.parseTime(createCallRequest.getStartTime()));
|
|
callEntity.setEndTime(DateTimeUtil.parseTime(createCallRequest.getEndTime()));
|
|
callEntity.setHub(userEntity.getHub());
|
|
callEntity.setNumberOfCheck(createCallRequest.getNumberOfCheck());
|
|
callEntity.setAppointmentTemplateId(createCallRequest.getAppointmentTemplateId());
|
|
callEntity.setAllowMultipleApplications(false);
|
|
if (createCallRequest.getAllowMultipleApplications() != null) {
|
|
callEntity.setAllowMultipleApplications(createCallRequest.getAllowMultipleApplications());
|
|
}
|
|
if (createCallRequest.getRankingType() != null) {
|
|
callEntity.setRankingType(createCallRequest.getRankingType().getValue());
|
|
}
|
|
callEntity = callRepository.save(callEntity);
|
|
log.info("CallEntity saved with ID: {} for call name: '{}'", callEntity.getId(), callEntity.getName());
|
|
|
|
/** This code is responsible for adding a version history log for the "Create Call" operation. **/
|
|
loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.INSERT).oldData(null).newData(callEntity).build());
|
|
return callEntity;
|
|
}
|
|
|
|
public List<EvaluationCriteriaEntity> convertToEvaluationCriteriaEntities(
|
|
List<EvaluationCriteriaReq> criteriaReqList, CallEntity callEntity, LookUpDataTypeEnum type) {
|
|
if (criteriaReqList == null) {
|
|
return null;
|
|
}
|
|
List<EvaluationCriteriaEntity> existingCriteria = evaluationCriteriaRepository.findByCallIdAndLookupDataTypeAndIsDeletedFalse(callEntity.getId(), type.getValue());
|
|
|
|
List<Long> incomingIds = criteriaReqList.stream().map(EvaluationCriteriaReq::getId)
|
|
.filter(id -> id != null && id > 0).collect(Collectors.toList());
|
|
|
|
existingCriteria.stream().filter(criteria -> !incomingIds.contains(criteria.getId())).forEach(this::softDeleteEvaluationCriteria);
|
|
|
|
List<EvaluationCriteriaEntity> evaluationCriteriaEntities = criteriaReqList.stream()
|
|
.map(req -> convertToEvaluationCriteriaEntity(req, callEntity, type)).collect(Collectors.toList());
|
|
|
|
return evaluationCriteriaEntities;
|
|
}
|
|
|
|
private void softDeleteEvaluationCriteria(EvaluationCriteriaEntity evaluationCriteriaEntity) {
|
|
log.info("Starting soft delete for EvaluationCriteriaEntity with ID: {}", evaluationCriteriaEntity.getId());
|
|
EvaluationCriteriaEntity oldEvaluationCriteriaEntity = Utils.getClonedEntityForData(evaluationCriteriaEntity);
|
|
evaluationCriteriaEntity.setIsDeleted(true);
|
|
evaluationCriteriaRepository.save(evaluationCriteriaEntity);
|
|
log.info("Soft deleted EvaluationCriteriaEntity with ID: {}", evaluationCriteriaEntity.getId());
|
|
|
|
/** This code is responsible for adding a version history log for the "soft delete evaluation criteria" operation **/
|
|
loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.SOFT_DELETE).oldData(oldEvaluationCriteriaEntity).newData(evaluationCriteriaEntity).build());
|
|
|
|
List<CriteriaFormFieldEntity> list = criteriaFormFieldRepository
|
|
.findByEvaluationCriteriaIdAndIsDeletedFalse(evaluationCriteriaEntity.getId());
|
|
|
|
if(Boolean.FALSE.equals(CollectionUtils.isEmpty(list))) {
|
|
|
|
list.stream().peek(data->{
|
|
CriteriaFormFieldEntity oldCriteriaFormFieldEntity = Utils.getClonedEntityForData(data);
|
|
data.setIsDeleted(Boolean.TRUE);
|
|
|
|
/** This code is responsible for adding a version history log for the "soft delete criteria form field" operation **/
|
|
loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.SOFT_DELETE).oldData(oldCriteriaFormFieldEntity).newData(data).build());
|
|
});
|
|
criteriaFormFieldRepository.saveAll(list);
|
|
log.info("Soft deleted all linked CriteriaFormFieldEntity records for EvaluationCriteriaEntity ID: {}", evaluationCriteriaEntity.getId());
|
|
}
|
|
}
|
|
|
|
private EvaluationCriteriaEntity convertToEvaluationCriteriaEntity(EvaluationCriteriaReq criteriaReq,
|
|
CallEntity callEntity, LookUpDataTypeEnum type) {
|
|
EvaluationCriteriaEntity criteriaEntity = null;
|
|
EvaluationCriteriaEntity oldCriteriaEntity = null;
|
|
VersionActionTypeEnum actionType = VersionActionTypeEnum.INSERT;
|
|
LookUpDataEntity lookupDataEntity = lookUpDataService.getOrCreateLookUpDataEntity(criteriaReq, type);
|
|
if (criteriaReq.getId() != null && criteriaReq.getId() > 0) {
|
|
criteriaEntity = evaluationCriteriaRepository.findById(criteriaReq.getId())
|
|
.orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND,
|
|
Translator.toLocale(GepafinConstant.EVALUATION_CRITERIA_NOT_FOUND)));
|
|
oldCriteriaEntity = Utils.getClonedEntityForData(oldCriteriaEntity);
|
|
actionType = VersionActionTypeEnum.UPDATE;
|
|
} else {
|
|
criteriaEntity = new EvaluationCriteriaEntity();
|
|
criteriaEntity.setCall(callEntity);
|
|
criteriaEntity.setLookupData(lookupDataEntity);
|
|
criteriaEntity.setScore(BigDecimal.ZERO);
|
|
criteriaEntity.setIsDeleted(false);
|
|
actionType = VersionActionTypeEnum.INSERT;
|
|
}
|
|
setIfUpdated(criteriaEntity::getScore, criteriaEntity::setScore, criteriaReq.getScore());
|
|
if (Boolean.FALSE.equals(criteriaEntity.getLookupData().getId().equals(lookupDataEntity.getId()))) {
|
|
criteriaEntity.setLookupData(lookupDataEntity);
|
|
}
|
|
criteriaEntity = evaluationCriteriaRepository.save(criteriaEntity) ;
|
|
|
|
/** This code is responsible for adding a version history log for the "create or update evaluation criteria" operation **/
|
|
loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(actionType).oldData(oldCriteriaEntity).newData(criteriaEntity).build());
|
|
return criteriaEntity;
|
|
}
|
|
|
|
|
|
public List<DocumentEntity> convertToDocumentEntities(List<DocumentReq> documentReqList, Long sourceId,
|
|
DocumentTypeEnum documentType) {
|
|
if (documentReqList == null) {
|
|
return null;
|
|
}
|
|
|
|
List<DocumentEntity> existingDocuments = documentRepository
|
|
.findBySourceIdAndSourceAndTypeAndIsDeletedFalse(sourceId, DocumentSourceTypeEnum.CALL.getValue(), documentType.getValue());
|
|
|
|
List<Long> incomingIds = documentReqList.stream().map(DocumentReq::getId).filter(id -> id != null && id > 0)
|
|
.collect(Collectors.toList());
|
|
|
|
existingDocuments.stream().filter(document -> !incomingIds.contains(document.getId()))
|
|
.forEach(this::softDeleteDocument);
|
|
List<DocumentEntity> documentEntities = documentReqList.stream()
|
|
.map(req -> convertToDocumentEntity(req, sourceId)).collect(Collectors.toList());
|
|
// documentRepository.saveAll(documentEntities);
|
|
return documentEntities;
|
|
}
|
|
|
|
private void softDeleteDocument(DocumentEntity documentEntity) {
|
|
DocumentEntity oldDocumentEntity = Utils.getClonedEntityForData(documentEntity);
|
|
documentEntity.setIsDeleted(true);
|
|
documentEntity = documentRepository.save(documentEntity);
|
|
|
|
/** This code is responsible for adding a version history log for the "soft delete for document" operation **/
|
|
loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.SOFT_DELETE).oldData(oldDocumentEntity).newData(documentEntity).build());
|
|
|
|
|
|
}
|
|
|
|
private DocumentEntity convertToDocumentEntity(DocumentReq documentReq,Long sourceId) {
|
|
validateDocumentEntity(documentReq.getId());
|
|
DocumentEntity documentEntity = documentRepository.findByIdAndSourceIdAndSourceAndIsDeletedFalse(documentReq.getId(),sourceId, DocumentSourceTypeEnum.CALL.getValue())
|
|
.orElseThrow(() -> {
|
|
log.error("Document not found or already deleted. Document ID: {}, Source ID: {}", documentReq.getId(), sourceId);
|
|
return new ResourceNotFoundException(Status.NOT_FOUND,
|
|
Translator.toLocale(GepafinConstant.DOCUMENT_NOT_FOUND));
|
|
});
|
|
return documentEntity;
|
|
}
|
|
|
|
public List<FaqEntity> updateFaq(List<FaqReq> faqReqList, CallEntity callEntity, UserEntity userEntity, LookUpDataTypeEnum type) {
|
|
if (faqReqList == null) {
|
|
return null;
|
|
}
|
|
List<FaqEntity> existingFaqEntities = faqRepository.findByCallIdAndIsDeletedFalse(callEntity.getId());
|
|
List<Long> incomingIds = faqReqList.stream()
|
|
.map(FaqReq::getId)
|
|
.filter(id -> id != null && id > 0)
|
|
.collect(Collectors.toList());
|
|
existingFaqEntities.stream()
|
|
.filter(entity -> !incomingIds.contains(entity.getId()))
|
|
.forEach(this::softDeleteFaq);
|
|
List<FaqEntity> faqEntities = faqReqList.stream()
|
|
.map(req -> faqService.createOrUpdateFaqEntity(req, callEntity, userEntity, type))
|
|
.collect(Collectors.toList());
|
|
return faqEntities;
|
|
}
|
|
|
|
|
|
public void validateDocumentEntity(Long documentId) {
|
|
if (documentId == null || documentId < 1) {
|
|
log.warn("Invalid Document ID provided: {}", documentId);
|
|
throw new CustomValidationException(Status.VALIDATION_ERROR,
|
|
Translator.toLocale(GepafinConstant.DOCUMENT_ID_NOT_FOUND));
|
|
}
|
|
}
|
|
|
|
public void validateEvaluationCriteriaEntity(String name) {
|
|
if (!StringUtils.hasText(name)) {
|
|
throw new CustomValidationException(Status.VALIDATION_ERROR,
|
|
Translator.toLocale(GepafinConstant.NAME_NOT_EMPTY_MSG));
|
|
}
|
|
}
|
|
|
|
public CallResponse convertToCallResponseBean(CallEntity callEntity) {
|
|
CallResponse createCallResponseBean = new CallResponse();
|
|
createCallResponseBean.setId(callEntity.getId());
|
|
createCallResponseBean.setName(callEntity.getName());
|
|
List<LocalDateTime> dates = new ArrayList<>();
|
|
dates.add(callEntity.getStartDate());
|
|
dates.add(callEntity.getEndDate());
|
|
createCallResponseBean.setDates(dates);
|
|
createCallResponseBean.setDescriptionShort(callEntity.getDescriptionShort());
|
|
createCallResponseBean.setDescriptionLong(callEntity.getDescriptionLong());
|
|
createCallResponseBean.setStatus(CallStatusEnum.valueOf(callEntity.getStatus()));
|
|
createCallResponseBean.setEvaluationVersion(EvaluationVersionEnum.valueOf(callEntity.getEvaluationVersion()));
|
|
createCallResponseBean.setRegionId(callEntity.getRegion().getId());
|
|
createCallResponseBean.setAmount(callEntity.getAmount());
|
|
createCallResponseBean.setAmountMax(callEntity.getAmountMax());
|
|
createCallResponseBean.setContactInfo(callEntity.getContactInfo());
|
|
createCallResponseBean.setSubmissionMethod(callEntity.getSubmissionMethod());
|
|
createCallResponseBean.setThreshold(callEntity.getThreshold());
|
|
createCallResponseBean.setDocumentationRequested(callEntity.getDocumentationRequested());
|
|
createCallResponseBean.setPriorityArea(callEntity.getPriorityArea());
|
|
createCallResponseBean.setConfidi(callEntity.getConfidi());
|
|
createCallResponseBean.setAllowMultipleApplications(callEntity.getAllowMultipleApplications());
|
|
createCallResponseBean.setAmountMin(callEntity.getAmountMin());
|
|
createCallResponseBean.setPhoneNumber(callEntity.getPhoneNumber());
|
|
createCallResponseBean.setEndTime(callEntity.getEndTime());
|
|
createCallResponseBean.setStartTime(callEntity.getStartTime());
|
|
createCallResponseBean.setEmail(callEntity.getEmail());
|
|
createCallResponseBean.setCreatedDate(callEntity.getCreatedDate());
|
|
createCallResponseBean.setUpdatedDate(callEntity.getUpdatedDate());
|
|
if (callEntity.getRankingType() != null && !callEntity.getRankingType().isBlank()) {
|
|
createCallResponseBean.setRankingType(CallRankingTypeEnum.valueOf(callEntity.getRankingType().trim()));
|
|
}
|
|
return createCallResponseBean;
|
|
}
|
|
|
|
public EvaluationCriteriaResponseBean convertToEvaluationCriteriaResponseBean(EvaluationCriteriaEntity entity) {
|
|
EvaluationCriteriaResponseBean responseBean = new EvaluationCriteriaResponseBean();
|
|
responseBean.setId(entity.getId());
|
|
responseBean.setLookUpDataId(entity.getLookupData().getId());
|
|
responseBean.setTitle(entity.getLookupData().getTitle());
|
|
responseBean.setValue(entity.getLookupData().getValue());
|
|
responseBean.setResponse(entity.getLookupData().getResponse());
|
|
responseBean.setScore(entity.getScore());
|
|
responseBean.setCreatedDate(entity.getCreatedDate());
|
|
responseBean.setUpdatedDate(entity.getUpdatedDate());
|
|
return responseBean;
|
|
}
|
|
|
|
public DocumentResponseBean convertToDocumentResponseBean(DocumentEntity entity) {
|
|
DocumentResponseBean responseBean = new DocumentResponseBean();
|
|
responseBean.setId(entity.getId());
|
|
responseBean.setName(entity.getFileName());
|
|
responseBean.setType(DocumentTypeEnum.valueOf(entity.getType()));
|
|
responseBean.setSource(DocumentSourceTypeEnum.valueOf(entity.getSource()));
|
|
responseBean.setSourceId(entity.getSourceId());
|
|
responseBean.setFilePath(entity.getFilePath());
|
|
responseBean.setCreatedDate(entity.getCreatedDate());
|
|
responseBean.setUpdatedDate(entity.getUpdatedDate());
|
|
return responseBean;
|
|
}
|
|
|
|
public CallResponse assembleCreateCallResponseBean(CallEntity callEntity,
|
|
List<EvaluationCriteriaEntity> evaluationCriteriaEntities, List<DocumentEntity> documentEntities,
|
|
List<DocumentEntity> images) {
|
|
|
|
CallResponse callResponseBean = convertToCallResponseBean(callEntity);
|
|
|
|
List<EvaluationCriteriaResponseBean> evaluationCriteriaResponseBeans = evaluationCriteriaEntities.stream()
|
|
.map(this::convertToEvaluationCriteriaResponseBean).collect(Collectors.toList());
|
|
|
|
List<DocumentResponseBean> documentResponseBeans = documentEntities.stream()
|
|
.map(this::convertToDocumentResponseBean).collect(Collectors.toList());
|
|
|
|
|
|
List<DocumentResponseBean> imagesResponseBean = images.stream().map(this::convertToDocumentResponseBean)
|
|
.collect(Collectors.toList());
|
|
CallResponse createCallResponseBean = callResponseBean;
|
|
createCallResponseBean.setCriteria(evaluationCriteriaResponseBeans);
|
|
createCallResponseBean.setDocs(documentResponseBeans);
|
|
createCallResponseBean.setImages(imagesResponseBean);
|
|
return createCallResponseBean;
|
|
}
|
|
|
|
// public List<LookUpDataResponse> convertLookUpDataEntities(List<LookUpDataReq> lookUpData, CallEntity callEntity,
|
|
// LookUpDataEntity.LookUpDataTypeEnum type) {
|
|
// if(lookUpData == null) {
|
|
// return null;
|
|
// }
|
|
// List<LookUpDataEntity> lookUpDataEntities = lookUpData.stream()
|
|
// .map(req -> lookUpDataService.getOrCreateLookUpDataEntity(req, type)).collect(Collectors.toList());
|
|
//
|
|
// return createCallTargetAudienceCheckList(callEntity, lookUpDataEntities);
|
|
// }
|
|
|
|
// private List<LookUpDataResponse> createCallTargetAudienceCheckList(CallEntity callEntity,
|
|
// List<LookUpDataEntity> lookUpDataEntities) {
|
|
// List<LookUpDataResponse> lookUpDataResponses = new ArrayList<>();
|
|
// for (LookUpDataEntity lookUpDataEntity : lookUpDataEntities) {
|
|
// CallTargetAudienceChecklistEntity callTargetAudienceChecklistEntity = new CallTargetAudienceChecklistEntity();
|
|
// callTargetAudienceChecklistEntity.setIsValidated(false);
|
|
// callTargetAudienceChecklistEntity.setLookupData(lookUpDataEntity);
|
|
// callTargetAudienceChecklistEntity.setCall(callEntity);
|
|
// callTargetAudienceChecklistEntity.setIsDeleted(false);
|
|
// callTargetAudienceChecklistEntity = callTargetAudienceChecklistRepository
|
|
// .save(callTargetAudienceChecklistEntity);
|
|
// versionHistoryRequest.setOldData(null);
|
|
// versionHistoryRequest.setNewData(callTargetAudienceChecklistEntity);
|
|
// versionHistoryRequest.setActionType(VersionActionTypeEnum.INSERT);
|
|
// versionHistoryRequest.setRequest(request);
|
|
// loggingUtil.addVersionHistory(versionHistoryRequest);
|
|
// lookUpDataResponses.add(convertToLookUpDataResponseBean(callTargetAudienceChecklistEntity));
|
|
// }
|
|
// return lookUpDataResponses;
|
|
// }
|
|
|
|
public LookUpDataResponse convertToLookUpDataResponseBean(
|
|
CallTargetAudienceChecklistEntity callTargetAudienceChecklistEntity) {
|
|
LookUpDataResponse lookUpDataResponse = new LookUpDataResponse();
|
|
LookUpDataEntity lookUpDataEntity = callTargetAudienceChecklistEntity.getLookupData();
|
|
lookUpDataResponse.setId(callTargetAudienceChecklistEntity.getId());
|
|
lookUpDataResponse.setLookUpDataId(lookUpDataEntity.getId());
|
|
lookUpDataResponse.setValue(lookUpDataEntity.getValue());
|
|
lookUpDataResponse.setTitle(lookUpDataEntity.getTitle());
|
|
lookUpDataResponse.setResponse(lookUpDataEntity.getResponse());
|
|
lookUpDataResponse.setCreatedDate(callTargetAudienceChecklistEntity.getCreatedDate());
|
|
lookUpDataResponse.setUpdatedDate(callTargetAudienceChecklistEntity.getUpdatedDate());
|
|
return lookUpDataResponse;
|
|
}
|
|
|
|
public CallEntity validateCall(Long callId) {
|
|
return callRepository.findById(callId).orElseThrow(() -> { log.error("Call not found for ID: {}", callId);
|
|
return new ResourceNotFoundException(Status.NOT_FOUND,
|
|
Translator.toLocale(GepafinConstant.CALL_NOT_FOUND));
|
|
});
|
|
}
|
|
|
|
public CallResponse getCallById(HttpServletRequest request,UserEntity user, CallEntity callEntity, Long companyId) {
|
|
Long userId = user.getId();
|
|
Long callId = callEntity.getId();
|
|
log.info("Fetching Call details for Call ID: {}, User ID: {}, Company ID: {}", callId, userId, companyId);
|
|
|
|
BeneficiaryPreferredCallEntity preferredCall;
|
|
if (companyId != null) {
|
|
validator.validateUserWithCompany(request, companyId);
|
|
UserWithCompanyEntity userWithCompanyEntity=companyService.getUserWithCompany(user.getId(),companyId);
|
|
preferredCall = beneficiaryPreferredCallRepository
|
|
.findByUserIdAndCallIdAndUserWithCompanyIdAndIsDeletedFalse(userId, callId, userWithCompanyEntity.getId())
|
|
.orElse(null);
|
|
} else {
|
|
preferredCall = beneficiaryPreferredCallRepository
|
|
.findByUserIdAndCallIdInAndIsDeletedFalse(userId, List.of(callId))
|
|
.stream()
|
|
.findFirst()
|
|
.orElse(null);
|
|
}
|
|
|
|
CallResponse callResponse = getCallResponseBean(callEntity);
|
|
callResponse.setPreferredCallId(preferredCall != null ? preferredCall.getId() : null);
|
|
|
|
return callResponse;
|
|
}
|
|
|
|
|
|
public CallResponse createCallStep2(CallEntity callEntity, CreateCallRequestStep2 createCallRequest, UserEntity user) {
|
|
// validateUpdate(callEntity);
|
|
log.info("Starting Call Step 2 update for Call ID: {}, User ID: {}", callEntity.getId(), user.getId());
|
|
if(createCallRequest.getThreshold() != null && Boolean.FALSE.equals(createCallRequest.getThreshold().equals(callEntity.getThreshold()))) {
|
|
CallEntity oldCallEntity = Utils.getClonedEntityForData(callEntity);
|
|
setIfUpdated(callEntity::getThreshold, callEntity::setThreshold, createCallRequest.getThreshold());
|
|
callEntity = callRepository.save(callEntity);
|
|
|
|
log.info("Updated threshold for Call ID: {}", callEntity.getId());
|
|
|
|
/** This code is responsible for adding a version history log for the "update call step 2" operation **/
|
|
loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldCallEntity).newData(callEntity).build());
|
|
}
|
|
convertToEvaluationCriteriaEntities(createCallRequest.getCriteria(), callEntity, LookUpDataTypeEnum.EVALUATION_CRITERIA);
|
|
|
|
convertToDocumentEntities(createCallRequest.getDocs(), callEntity.getId(), DocumentTypeEnum.DOCUMENT);
|
|
|
|
convertToDocumentEntities(createCallRequest.getImages(), callEntity.getId(), DocumentTypeEnum.IMAGES);
|
|
|
|
updateLookUpData(callEntity, createCallRequest.getCheckList(), LookUpDataTypeEnum.CHECKLIST);
|
|
|
|
CallResponse createCallResponseBean = getCallResponseBean(callEntity);
|
|
createCallResponseBean.setCurrentStep(GepafinConstant.STEP_2);
|
|
return createCallResponseBean;
|
|
}
|
|
|
|
public void validateUpdate(CallEntity callEntity) {
|
|
if(callEntity.getStatus().equals(CallStatusEnum.PUBLISH.getValue())) {
|
|
log.warn("Attempted update on published call. Call ID: {}", callEntity.getId());
|
|
throw new CustomValidationException(Status.VALIDATION_ERROR,
|
|
Translator.toLocale(GepafinConstant.PUBLISHED_CALL_NOT_UPDATE));
|
|
}
|
|
}
|
|
|
|
private boolean hasNonRankingStep1Field(UpdateCallRequestStep1 r) {
|
|
return r.getName() != null
|
|
|| r.getDescriptionShort() != null
|
|
|| r.getDescriptionLong() != null
|
|
|| r.getDates() != null
|
|
|| r.getAmount() != null
|
|
|| r.getAmountMax() != null
|
|
|| r.getAimedTo() != null
|
|
|| r.getDocumentationRequested() != null
|
|
|| r.getAmountMin() != null
|
|
|| r.getEmail() != null
|
|
|| r.getPhoneNumber() != null
|
|
|| r.getStartTime() != null
|
|
|| r.getEndTime() != null
|
|
|| r.getConfidi() != null
|
|
|| r.getAllowMultipleApplications() != null
|
|
|| r.getFaq() != null
|
|
|| r.getNumberOfCheck() != null
|
|
|| r.getAppointmentTemplateId() != null
|
|
|| r.getEvaluationVersion() != null;
|
|
}
|
|
|
|
private CallResponse updatePublishedCallStep1RankingTypeOnly(HttpServletRequest request, CallEntity callEntity,
|
|
CallEntity oldCallEntity, UpdateCallRequestStep1 updateCallRequest) {
|
|
setIfUpdated(callEntity::getRankingType, callEntity::setRankingType,
|
|
updateCallRequest.getRankingType() != null ? updateCallRequest.getRankingType().getValue() : null);
|
|
callEntity = callRepository.save(callEntity);
|
|
loggingUtil.addVersionHistory(
|
|
VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldCallEntity).newData(callEntity).build());
|
|
CallResponse response = getCallResponseBean(callEntity);
|
|
response.setCurrentStep(GepafinConstant.STEP_1);
|
|
log.info("Published call step 1: ranking type only | callId={}", callEntity.getId());
|
|
return response;
|
|
}
|
|
|
|
public void isValidDateRange(UpdateCallRequestStep1 updateCallRequest, CallEntity callEntity) {
|
|
List<LocalDateTime> dates = updateCallRequest.getDates();
|
|
|
|
LocalDate startDate = (dates != null && dates.size() > 0 && dates.get(0) != null)
|
|
? dates.get(0).toLocalDate()
|
|
: null;
|
|
|
|
LocalDate endDate = (dates != null && dates.size() > 1 && dates.get(1) != null)
|
|
? dates.get(1).toLocalDate()
|
|
: null;
|
|
|
|
Boolean isValid = true;
|
|
if (startDate != null && endDate != null && startDate.isAfter(endDate)) {
|
|
isValid = false;
|
|
} else if (startDate != null && endDate == null && callEntity.getEndDate() != null
|
|
&& startDate.isAfter(callEntity.getEndDate().toLocalDate())) {
|
|
isValid = false;
|
|
} else if (startDate == null && endDate != null && callEntity.getStartDate() != null
|
|
&& callEntity.getStartDate().toLocalDate().isAfter(endDate)) {
|
|
isValid = false;
|
|
}
|
|
|
|
if (Boolean.FALSE.equals(isValid)) {
|
|
log.error("Invalid date range detected for Call ID: {}", callEntity.getId());
|
|
throw new CustomValidationException(Status.VALIDATION_ERROR,
|
|
Translator.toLocale(GepafinConstant.INVALID_DATE_MSG));
|
|
}
|
|
}
|
|
|
|
public CallResponse updateCallStep1(HttpServletRequest request,CallEntity callEntity, UpdateCallRequestStep1 updateCallRequest, UserEntity userEntity) {
|
|
log.info("Updating Call ID: {}, by User ID: {}", callEntity.getId(),userEntity.getId() );
|
|
CallEntity oldCallEntity = Utils.getClonedEntityForData(callEntity);
|
|
if (CallStatusEnum.PUBLISH.getValue().equals(callEntity.getStatus())) {
|
|
if (hasNonRankingStep1Field(updateCallRequest)) {
|
|
throw new CustomValidationException(Status.VALIDATION_ERROR,
|
|
Translator.toLocale(GepafinConstant.PUBLISHED_CALL_STEP1_ONLY_RANKING_TYPE_ALLOWED));
|
|
}
|
|
if (updateCallRequest.getRankingType() != null) {
|
|
return updatePublishedCallStep1RankingTypeOnly(request, callEntity, oldCallEntity, updateCallRequest);
|
|
}
|
|
CallResponse unchanged = getCallResponseBean(callEntity);
|
|
unchanged.setCurrentStep(GepafinConstant.STEP_1);
|
|
return unchanged;
|
|
}
|
|
isValidDateRange(updateCallRequest, callEntity);
|
|
setIfUpdated(callEntity::getName, callEntity::setName, updateCallRequest.getName());
|
|
setIfUpdated(callEntity::getDescriptionShort, callEntity::setDescriptionShort,
|
|
updateCallRequest.getDescriptionShort());
|
|
setIfUpdated(callEntity::getDescriptionLong, callEntity::setDescriptionLong,
|
|
updateCallRequest.getDescriptionLong());
|
|
List<LocalDateTime> dates=updateCallRequest.getDates();
|
|
boolean isEndDateUpdated = false;
|
|
boolean isEndTimeUpdated = false;
|
|
if (dates != null && dates.size()>1) {
|
|
if (dates.size() > 0) {
|
|
setIfUpdated(callEntity::getStartDate, callEntity::setStartDate, dates.get(0));
|
|
}
|
|
// if (dates.size() > 1) {
|
|
// LocalDate requestEndDate = dates.get(1).toLocalDate(); // Extract only the date
|
|
// LocalDate storedEndDate = callEntity.getEndDate().toLocalDate(); // Extract only the date
|
|
//
|
|
// if (!requestEndDate.equals(storedEndDate)) { // Check if dates are different
|
|
//
|
|
// setIfUpdated(callEntity::getEndDate, callEntity::setEndDate, dates.get(1));
|
|
//// callEntity.setStatus(CallStatusEnum.PUBLISH.getValue());
|
|
//// callRepository.save(callEntity);
|
|
// isEndDateUpdated = true;
|
|
// }
|
|
// }
|
|
// }
|
|
|
|
if (updateCallRequest.getEndTime() != null) {
|
|
LocalTime requestEndTime = DateTimeUtil.parseTime(updateCallRequest.getEndTime());
|
|
LocalTime storedEndTime = callEntity.getEndTime();
|
|
|
|
if (!requestEndTime.equals(storedEndTime)) {
|
|
setIfUpdated(callEntity::getEndTime, callEntity::setEndTime, DateTimeUtil.parseTime(updateCallRequest.getEndTime()));
|
|
isEndTimeUpdated = true;
|
|
}
|
|
}
|
|
if (dates.size() > 1) {
|
|
LocalDate requestEndDate = dates.get(1).toLocalDate(); // Extract only the date
|
|
LocalDate storedEndDate = callEntity.getEndDate().toLocalDate(); // Extract only the date
|
|
|
|
if (!requestEndDate.equals(storedEndDate)) {
|
|
// Check if dates are different
|
|
|
|
setIfUpdated(callEntity::getEndDate, callEntity::setEndDate, dates.get(1));
|
|
if(callEntity.getStatus().equals(CallStatusEnum.EXPIRED.getValue())) {
|
|
LocalDateTime newEndDate = LocalDateTime.of(requestEndDate, callEntity.getEndTime());
|
|
if(newEndDate.isBefore(LocalDateTime.now())){
|
|
throw new CustomValidationException(Status.VALIDATION_ERROR,Translator.toLocale(GepafinConstant.END_DATE_GREATER_THAN_NOW));
|
|
}
|
|
|
|
if (requestEndDate.isAfter(LocalDate.now()) || requestEndDate.isEqual(LocalDate.now())) {
|
|
callEntity.setStatus(CallStatusEnum.PUBLISH.getValue());
|
|
callRepository.save(callEntity);
|
|
}
|
|
}
|
|
isEndDateUpdated = true;
|
|
}
|
|
}
|
|
}
|
|
if (isEndDateUpdated || isEndTimeUpdated) {
|
|
callRepository.save(callEntity);
|
|
loggingUtil.logUserAction(UserActionRequest.builder()
|
|
.request(request)
|
|
.actionType(UserActionLogsEnum.UPDATE)
|
|
.actionContext(UserActionContextEnum.UPDATE_CALL_END_DATE_AND_TIME)
|
|
.build());
|
|
|
|
/** This code is responsible for adding a version history log for the "update call end date and time" operation **/
|
|
loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldCallEntity).newData(callEntity).build());
|
|
}
|
|
|
|
// setIfUpdated(callEntity::getStartDate, callEntity::setStartDate, updateCallRequest.getStartDate());
|
|
// setIfUpdated(callEntity::getEndDate, callEntity::setEndDate, updateCallRequest.getEndDate());
|
|
setIfUpdated(callEntity::getAmount, callEntity::setAmount, updateCallRequest.getAmount());
|
|
setIfUpdated(callEntity::getAmountMax, callEntity::setAmountMax, updateCallRequest.getAmountMax());
|
|
setIfUpdated(callEntity::getDocumentationRequested, callEntity::setDocumentationRequested,
|
|
updateCallRequest.getDocumentationRequested());
|
|
|
|
if (updateCallRequest.getAmountMin() != null && updateCallRequest.getAmountMin().compareTo(BigDecimal.ZERO) < 0) {
|
|
log.error("Validation failed: Invalid email {} for Call ID: {}", updateCallRequest.getEmail(), callEntity.getId());
|
|
throw new CustomValidationException(Status.VALIDATION_ERROR,Translator.toLocale(GepafinConstant.AMOUNT_GREATER_THAN_ZERO_MSG));
|
|
}
|
|
if(updateCallRequest.getEmail()!=null && Boolean.FALSE.equals(Utils.isValidEmail(updateCallRequest.getEmail()))){
|
|
log.error("Validation failed: Invalid email {} for Call ID: {}", updateCallRequest.getEmail(), callEntity.getId());
|
|
throw new CustomValidationException(Status.VALIDATION_ERROR,Translator.toLocale(GepafinConstant.VALIDATION_EMAIL,updateCallRequest.getEmail()));
|
|
}
|
|
setIfUpdated(callEntity::getAmountMin, callEntity::setAmountMin, updateCallRequest.getAmountMin());
|
|
setIfUpdated(callEntity::getEmail, callEntity::setEmail, updateCallRequest.getEmail());
|
|
setIfUpdated(callEntity::getPhoneNumber, callEntity::setPhoneNumber, updateCallRequest.getPhoneNumber());
|
|
setIfUpdated(callEntity::getStartTime, callEntity::setStartTime, DateTimeUtil.parseTime(updateCallRequest.getStartTime()));
|
|
setIfUpdated(callEntity::getConfidi, callEntity::setConfidi, updateCallRequest.getConfidi());
|
|
if (updateCallRequest.getEvaluationVersion() != null) {
|
|
setIfUpdated(callEntity::getEvaluationVersion, callEntity::setEvaluationVersion,
|
|
updateCallRequest.getEvaluationVersion().getValue());
|
|
}
|
|
setIfUpdated(callEntity::getNumberOfCheck, callEntity::setNumberOfCheck, updateCallRequest.getNumberOfCheck());
|
|
setIfUpdated(callEntity::getAppointmentTemplateId, callEntity::setAppointmentTemplateId, updateCallRequest.getAppointmentTemplateId());
|
|
setIfUpdated(callEntity::getAllowMultipleApplications, callEntity::setAllowMultipleApplications, updateCallRequest.getAllowMultipleApplications());
|
|
setIfUpdated(callEntity::getRankingType, callEntity::setRankingType,
|
|
updateCallRequest.getRankingType() != null ? updateCallRequest.getRankingType().getValue() : null);
|
|
callEntity = callRepository.save(callEntity);
|
|
|
|
/** This code is responsible for adding a version history log for the "update call step 1" operation **/
|
|
loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldCallEntity).newData(callEntity).build());
|
|
|
|
updateLookUpData(callEntity, updateCallRequest.getAimedTo(), LookUpDataTypeEnum.AIMED_TO);
|
|
updateFaq(updateCallRequest.getFaq(), callEntity, userEntity, LookUpDataTypeEnum.FAQ);
|
|
CallResponse createCallResponseBean = getCallResponseBean(callEntity);
|
|
createCallResponseBean.setCurrentStep(GepafinConstant.STEP_1);
|
|
log.info("Call Step 1 update completed for Call ID: {}", callEntity.getId());
|
|
return createCallResponseBean;
|
|
}
|
|
|
|
public CallResponse updateCallRankingType(HttpServletRequest request, CallEntity callEntity, CallRankingTypeEnum rankingType) {
|
|
CallEntity oldCallEntity = Utils.getClonedEntityForData(callEntity);
|
|
callEntity.setRankingType(rankingType != null ? rankingType.getValue() : null);
|
|
callEntity = callRepository.save(callEntity);
|
|
loggingUtil.addVersionHistory(
|
|
VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldCallEntity).newData(callEntity).build());
|
|
return getCallResponseBean(callEntity);
|
|
}
|
|
|
|
private void softDeleteFaq(FaqEntity faqEntity) {
|
|
|
|
FaqEntity oldFaqEntity = Utils.getClonedEntityForData(faqEntity);
|
|
|
|
faqEntity.setIsDeleted(true);
|
|
faqRepository.save(faqEntity);
|
|
|
|
/** This code is responsible for adding a version history log for the "soft delete faq" operation **/
|
|
loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.SOFT_DELETE).oldData(oldFaqEntity).newData(faqEntity).build());
|
|
}
|
|
|
|
private void updateLookUpData(CallEntity callEntity, List<LookUpDataReq> lookupDataReqList, LookUpDataTypeEnum type) {
|
|
if (lookupDataReqList == null) {
|
|
return;
|
|
}
|
|
List<CallTargetAudienceChecklistEntity> existingChecklist = callTargetAudienceChecklistRepository
|
|
.findByCallIdAndLookupDataTypeAndIsDeletedFalse(callEntity.getId(), type.getValue());
|
|
List<Long> incomingIds = lookupDataReqList.stream().map(LookUpDataReq::getId)
|
|
.filter(id -> id != null && id > 0).collect(Collectors.toList());
|
|
existingChecklist.stream().filter(checklist -> !incomingIds.contains(checklist.getId()))
|
|
.forEach(this::softDeleteCallTargetAudienceChecklist);
|
|
lookupDataReqList
|
|
.forEach(lookUpDataReq -> createOrUpdateCallTargetAudienceChecklist(lookUpDataReq, callEntity, type));
|
|
}
|
|
|
|
private void createOrUpdateCallTargetAudienceChecklist(LookUpDataReq lookUpDataReq, CallEntity callEntity,
|
|
LookUpDataTypeEnum type) {
|
|
CallTargetAudienceChecklistEntity checklistEntity = null;
|
|
CallTargetAudienceChecklistEntity oldChecklistEntity = null;
|
|
VersionActionTypeEnum actionType = VersionActionTypeEnum.INSERT;
|
|
LookUpDataEntity lookupDataEntity = lookUpDataService.getOrCreateLookUpDataEntity(lookUpDataReq, type);
|
|
if (lookUpDataReq.getId() != null && lookUpDataReq.getId() > 0) {
|
|
checklistEntity = callTargetAudienceChecklistRepository.findById(lookUpDataReq.getId())
|
|
.orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND,
|
|
Translator.toLocale(GepafinConstant.CALL_NOT_FOUND)));
|
|
|
|
if (Boolean.FALSE.equals(checklistEntity.getLookupData().getId().equals(lookupDataEntity.getId()))) {
|
|
checklistEntity.setLookupData(lookupDataEntity);
|
|
}
|
|
oldChecklistEntity = Utils.getClonedEntityForData(checklistEntity);
|
|
actionType = VersionActionTypeEnum.UPDATE;
|
|
} else {
|
|
checklistEntity = new CallTargetAudienceChecklistEntity();
|
|
checklistEntity.setCall(callEntity);
|
|
checklistEntity.setLookupData(lookupDataEntity);
|
|
checklistEntity.setIsValidated(false);
|
|
checklistEntity.setIsDeleted(false);
|
|
actionType = VersionActionTypeEnum.INSERT;
|
|
}
|
|
|
|
checklistEntity = callTargetAudienceChecklistRepository.save(checklistEntity);
|
|
|
|
/** This code is responsible for adding a version history log for the "create or update aimedTo Checklist" operation **/
|
|
loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(actionType).oldData(oldChecklistEntity).newData(checklistEntity).build());
|
|
}
|
|
|
|
private void softDeleteCallTargetAudienceChecklist(
|
|
CallTargetAudienceChecklistEntity callTargetAudienceChecklistEntity) {
|
|
CallTargetAudienceChecklistEntity oldCallTargetAudienceChecklistEntity = Utils.getClonedEntityForData(callTargetAudienceChecklistEntity);
|
|
callTargetAudienceChecklistEntity.setIsDeleted(true);
|
|
callTargetAudienceChecklistRepository.save(callTargetAudienceChecklistEntity);
|
|
|
|
/** This code is responsible for adding a version history log for the "soft delete for aimedTo or Checklist" operation **/
|
|
loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.SOFT_DELETE).oldData(oldCallTargetAudienceChecklistEntity).newData(callTargetAudienceChecklistEntity).build());
|
|
}
|
|
|
|
public CallDetailsResponseBean convertToCallDetailsResponseBean(CallEntity callEntity) {
|
|
CallDetailsResponseBean callDetailsResponseBean = new CallDetailsResponseBean();
|
|
callDetailsResponseBean.setId(callEntity.getId());
|
|
callDetailsResponseBean.setName(callEntity.getName());
|
|
List<LocalDateTime> dates = new ArrayList<>();
|
|
dates.add(callEntity.getStartDate());
|
|
dates.add(callEntity.getEndDate());
|
|
callDetailsResponseBean.setDates(dates);
|
|
callDetailsResponseBean.setConfidi(callEntity.getConfidi());
|
|
callDetailsResponseBean.setDescriptionShort(callEntity.getDescriptionShort());
|
|
callDetailsResponseBean.setDescriptionLong(callEntity.getDescriptionLong());
|
|
callDetailsResponseBean.setStatus(CallStatusEnum.valueOf(callEntity.getStatus()));
|
|
callDetailsResponseBean.setEvaluationVersion(EvaluationVersionEnum.valueOf(callEntity.getEvaluationVersion()));
|
|
callDetailsResponseBean.setRegionId(callEntity.getRegion().getId());
|
|
callDetailsResponseBean.setAmount(callEntity.getAmount());
|
|
callDetailsResponseBean.setAmountMax(callEntity.getAmountMax());
|
|
callDetailsResponseBean.setContactInfo(callEntity.getContactInfo());
|
|
callDetailsResponseBean.setSubmissionMethod(callEntity.getSubmissionMethod());
|
|
callDetailsResponseBean.setThreshold(callEntity.getThreshold());
|
|
callDetailsResponseBean.setDocumentationRequested(callEntity.getDocumentationRequested());
|
|
callDetailsResponseBean.setPriorityArea(callEntity.getPriorityArea());
|
|
callDetailsResponseBean.setAmountMin(callEntity.getAmountMin());
|
|
callDetailsResponseBean.setEmail(callEntity.getEmail());
|
|
callDetailsResponseBean.setEndTime(callEntity.getEndTime());
|
|
callDetailsResponseBean.setStartTime(callEntity.getStartTime());
|
|
callDetailsResponseBean.setPhoneNumber(callEntity.getPhoneNumber());
|
|
callDetailsResponseBean.setCreatedDate(callEntity.getCreatedDate());
|
|
callDetailsResponseBean.setUpdatedDate(callEntity.getUpdatedDate());
|
|
callDetailsResponseBean.setNumberOfCheck(callEntity.getNumberOfCheck());
|
|
callDetailsResponseBean.setAppointmentTemplateId(callEntity.getAppointmentTemplateId());
|
|
callDetailsResponseBean.setAllowMultipleApplications(callEntity.getAllowMultipleApplications());
|
|
return callDetailsResponseBean;
|
|
}
|
|
|
|
private CallResponse getCallResponseBean(CallEntity callEntity) {
|
|
log.info("Building CallResponse for Call ID: {}", callEntity.getId());
|
|
List<DocumentEntity> documentEntities = documentRepository.findBySourceIdAndSourceAndTypeAndIsDeletedFalse(callEntity.getId(),DocumentSourceTypeEnum.CALL.getValue()
|
|
, DocumentTypeEnum.DOCUMENT.getValue());
|
|
List<DocumentEntity> imageEntities = documentRepository.findBySourceIdAndSourceAndTypeAndIsDeletedFalse(callEntity.getId(), DocumentSourceTypeEnum.CALL.getValue()
|
|
, DocumentTypeEnum.IMAGES.getValue());
|
|
List<LookUpDataResponse> amiedTo = callTargetAudienceChecklistRepository
|
|
.findByCallIdAndLookupDataTypeAndIsDeletedFalse(callEntity.getId(), LookUpDataTypeEnum.AIMED_TO.getValue()).stream()
|
|
.map(this::convertToLookUpDataResponseBean).toList();
|
|
|
|
List<LookUpDataResponse> checkList = callTargetAudienceChecklistRepository
|
|
.findByCallIdAndLookupDataTypeAndIsDeletedFalse(callEntity.getId(), LookUpDataTypeEnum.CHECKLIST.getValue()).stream()
|
|
.map(this::convertToLookUpDataResponseBean).toList();
|
|
List<EvaluationCriteriaEntity> evaluationCriteriaEntities = evaluationCriteriaRepository
|
|
.findByCallIdAndLookupDataTypeAndIsDeletedFalse(callEntity.getId(), LookUpDataTypeEnum.EVALUATION_CRITERIA.getValue());
|
|
|
|
CallResponse createCallResponseBean = assembleCreateCallResponseBean(callEntity, evaluationCriteriaEntities,
|
|
documentEntities, imageEntities);
|
|
createCallResponseBean.setFaq(faqService.getFaqByCallId(callEntity.getId()));
|
|
createCallResponseBean.setAimedTo(amiedTo);
|
|
createCallResponseBean.setCheckList(checkList);
|
|
createCallResponseBean.setNumberOfCheck(callEntity.getNumberOfCheck());
|
|
createCallResponseBean.setAppointmentTemplateId(callEntity.getAppointmentTemplateId());
|
|
return createCallResponseBean;
|
|
}
|
|
|
|
public List<CallDetailsResponseBean> getAllCalls(HttpServletRequest request,UserEntity user, Long companyId,Boolean onlyPreferredCall,Boolean onlyConfidiCall) {
|
|
String type = user.getRoleEntity().getRoleType();
|
|
log.info("Fetching calls for User ID: {}, Role: {}, Company ID: {}, onlyPreferredCall: {}, onlyConfidiCall: {}",
|
|
user.getId(), type, companyId, onlyPreferredCall, onlyConfidiCall);
|
|
|
|
List<String> callStatusList = CallStatusEnum.getStatusValues();
|
|
if (Boolean.FALSE.equals(ROLE_SUPER_ADMIN.getValue().equals(type))) {
|
|
callStatusList = List.of(CallStatusEnum.PUBLISH.getValue());
|
|
}
|
|
// List<CallEntity> calls = List.of();
|
|
if (Boolean.TRUE.equals(onlyPreferredCall) && companyId == null) {
|
|
throw new CustomValidationException(Status.VALIDATION_ERROR,
|
|
Translator.toLocale(GepafinConstant.COMPANY_ID_REQUIRED_FOR_PREFERRED_CALL));
|
|
}
|
|
expirePublishedCalls(request);
|
|
Specification<CallEntity> spec = buildCallSpecification(request, user, companyId, onlyPreferredCall, onlyConfidiCall, callStatusList);
|
|
|
|
List<CallEntity> calls = callRepository.findAll(spec);
|
|
|
|
LocalDateTime now = LocalDateTime.now();
|
|
for (CallEntity call : calls) {
|
|
CallEntity oldCallEntity = Utils.getClonedEntityForData(call);
|
|
if (CallStatusEnum.PUBLISH.getValue().equals(call.getStatus()) &&
|
|
call.getEndDate() != null && call.getEndTime() != null) {
|
|
LocalDateTime callEndDateTime = LocalDateTime.of(LocalDate.from(call.getEndDate()), call.getEndTime());
|
|
if (callEndDateTime.isBefore(now)) {
|
|
log.info("Call ID: {} has expired. Updating status from PUBLISH to EXPIRED.", call.getId());
|
|
call.setStatus(CallStatusEnum.EXPIRED.getValue());
|
|
callRepository.save(call);
|
|
}
|
|
if (Boolean.FALSE.equals(oldCallEntity.getStatus().equals(call.getStatus()))) {
|
|
|
|
loggingUtil.logUserAction(UserActionRequest.builder()
|
|
.request(request)
|
|
.actionType(UserActionLogsEnum.UPDATE)
|
|
.actionContext(UserActionContextEnum.UPDATE_EXPIRED_CALL)
|
|
.build());
|
|
|
|
/** This code is responsible for adding a version history log for the "update call status to EXPIRED" operation **/
|
|
loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldCallEntity).newData(call).build());
|
|
}
|
|
}
|
|
}
|
|
|
|
List<Long> callIds = calls.stream().map(CallEntity::getId).collect(Collectors.toList());
|
|
Map<String, BeneficiaryPreferredCallEntity> preferredCallsMap =
|
|
getBeneficiaryPreferredCallsForUser(request,user, callIds, companyId);
|
|
|
|
return calls.stream()
|
|
.map(call -> {
|
|
CallDetailsResponseBean responseBean = convertToCallDetailsResponseBean(call);
|
|
String key = user.getId() + "_" + call.getId();
|
|
BeneficiaryPreferredCallEntity preferredCall = preferredCallsMap.get(key);
|
|
Long preferredId = (preferredCall != null && !preferredCall.getIsDeleted()) ? preferredCall.getId() : null;
|
|
responseBean.setPreferredCallId(preferredId);
|
|
|
|
return responseBean;
|
|
})
|
|
.collect(Collectors.toList());
|
|
}
|
|
|
|
public Map<String, BeneficiaryPreferredCallEntity> getBeneficiaryPreferredCallsForUser(HttpServletRequest request, UserEntity user, List<Long> callIds, Long companyId) {
|
|
log.info("Fetching preferred calls for User ID: {}, Company ID: {}, Call IDs: {}", user.getId(), companyId, callIds);
|
|
List<BeneficiaryPreferredCallEntity> beneficiaryPreferredCalls;
|
|
|
|
if (companyId != null && (Boolean.TRUE.equals(validator.checkIsBeneficiary()) || Boolean.TRUE.equals(validator.checkIsConfidi()))) {
|
|
log.info("Validating user with company for preferred calls: User ID: {}, Company ID: {}", user.getId(), companyId);
|
|
validator.validateUserWithCompany(request, companyId);
|
|
UserWithCompanyEntity userWithCompanyEntity=companyService.getUserWithCompany(user.getId(),companyId);
|
|
beneficiaryPreferredCalls = beneficiaryPreferredCallRepository
|
|
.findByUserIdAndCallIdInAndUserWithCompanyIdAndIsDeletedFalse(user.getId(), callIds, userWithCompanyEntity.getId());
|
|
} else {
|
|
log.info("Fetching preferred calls without company filtering for User ID: {}", user.getId());
|
|
beneficiaryPreferredCalls = beneficiaryPreferredCallRepository
|
|
.findByUserIdAndCallIdInAndIsDeletedFalse(user.getId(), callIds);
|
|
beneficiaryPreferredCalls = beneficiaryPreferredCalls.stream()
|
|
.collect(Collectors.collectingAndThen(
|
|
Collectors.toMap(
|
|
BeneficiaryPreferredCallEntity::getCallId,
|
|
call -> call,
|
|
(existing, replacement) -> existing
|
|
),
|
|
map -> new ArrayList<>(map.values())
|
|
));
|
|
|
|
}
|
|
|
|
return beneficiaryPreferredCalls.stream()
|
|
.collect(Collectors.toMap(
|
|
call -> user.getId() + "_" + call.getCallId(),
|
|
call -> call
|
|
));
|
|
}
|
|
|
|
|
|
public CallResponse validateCallData(CallEntity callEntity) {
|
|
log.info("Starting call validation for Call ID: {}, Current Status: {}", callEntity.getId(), callEntity.getStatus());
|
|
CallEntity oldCallEntity = Utils.getClonedEntityForData(callEntity);
|
|
validateUpdate(callEntity);
|
|
CallResponse callResponseBean = getCallResponseBean(callEntity);
|
|
FlowResponseBean flowResponseBean = flowDao.getFlowByCallId(callEntity.getId());
|
|
List<FormResponseBean> formResponseBean = formDao.getFormsByCallId(callEntity);
|
|
EvaluationFormResponseBean evaluationFormResponseBean = evalualtionFormDao.getEvaluationFormByCallId(callEntity);
|
|
CallValidatorServiceImpl.validateResponse(callResponseBean,flowResponseBean,formResponseBean,evaluationFormResponseBean);
|
|
callEntity.setStatus(CallStatusEnum.READY_TO_PUBLISH.getValue());
|
|
callEntity = callRepository.save(callEntity);
|
|
log.info("Call status updated to READY_TO_PUBLISH for Call ID: {}", callEntity.getId());
|
|
|
|
/** This code is responsible for adding a version history log for the "validate call" operation **/
|
|
loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldCallEntity).newData(callEntity).build());
|
|
|
|
callResponseBean.setCurrentStep(GepafinConstant.VALIDATE_REQUEST);
|
|
callResponseBean.setStatus(CallStatusEnum.valueOf(callEntity.getStatus()));
|
|
return callResponseBean;
|
|
}
|
|
// public CallEntity getCallEntityById(Long id){
|
|
// CallEntity callEntity=callRepository.findByIdAndStatusNotInAndHubId(id, List.of(CallStatusEnum.PUBLISH.getValue()));
|
|
// if(callEntity==null){
|
|
// throw new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.CALL_NOT_FOUND));
|
|
// }
|
|
// return callEntity;
|
|
// }
|
|
|
|
public CallResponse updateCallStatus(CallEntity callEntity, CallStatusEnum statusReq) {
|
|
log.info("Updating call status for Call ID: {} from {} to {}", callEntity.getId(), callEntity.getStatus(), statusReq);
|
|
CallEntity oldCallEntity = Utils.getClonedEntityForData(callEntity);
|
|
CallStatusEnum currentStatus = CallStatusEnum.valueOf(callEntity.getStatus());
|
|
validateStatusChange(currentStatus, statusReq, callEntity.getId());
|
|
callEntity.setStatus(statusReq.getValue());
|
|
callEntity = callRepository.save(callEntity);
|
|
log.info("Call status updated in DB for Call ID: {}. New Status: {}", callEntity.getId(), callEntity.getStatus());
|
|
|
|
//Creating notification.
|
|
List<Long> userIds = beneficiaryRepository.findUserIdsByHubIdAndBeneficiaryId(callEntity.getHub().getId());
|
|
Map<String, String> placeholders = new HashMap<>();
|
|
placeholders.put("{{call_name}}", callEntity.getName());
|
|
userIds.forEach(userId -> {
|
|
List<Long> companyIds = notificationDao.getAllCompanyIdsForUser(userId);
|
|
NotificationReq notificationReq = notificationDao.createNotificationReq(NotificationTypeEnum.CALL_CREATED.getValue(), placeholders, userId, null, companyIds);
|
|
notificationDao.sendNotification(notificationReq);
|
|
});
|
|
|
|
/** This code is responsible for adding a version history log for the "update call status" operation **/
|
|
loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldCallEntity).newData(callEntity).build());
|
|
|
|
return convertToCallResponseBean(callEntity);
|
|
}
|
|
|
|
private void validateStatusChange(CallStatusEnum currentStatus, CallStatusEnum newStatus, Long callId) {
|
|
log.info("Validating status change for Call ID: {} from '{}' to '{}'", callId, currentStatus, newStatus);
|
|
if (currentStatus == newStatus) {
|
|
log.warn("Validation failed: current status and new status are the same for Call ID: {}", callId);
|
|
throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.STATUS_SAME_ERROR));
|
|
}
|
|
switch (currentStatus) {
|
|
case DRAFT:
|
|
if (newStatus == CallStatusEnum.READY_TO_PUBLISH || newStatus == CallStatusEnum.PUBLISH) {
|
|
log.warn("Invalid status change attempt from DRAFT to {} for Call ID: {}", newStatus, callId);
|
|
throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.INVALID_STATUS_CHANGE_FROM_DRAFT));
|
|
}
|
|
break;
|
|
|
|
case PUBLISH:
|
|
if (newStatus == CallStatusEnum.READY_TO_PUBLISH) {
|
|
log.warn("Invalid status change attempt from PUBLISH to READY_TO_PUBLISH for Call ID: {}", callId);
|
|
throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.INVALID_STATUS_CHANGE_FROM_PUBLISH));
|
|
}
|
|
if (newStatus == CallStatusEnum.DRAFT && Boolean.TRUE.equals(applicationRepository.existsByCallId(callId))) {
|
|
log.warn("Invalid status change attempt from PUBLISH to DRAFT for Call ID: {} due to existing applications", callId);
|
|
throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.INVALID_STATUS_CHANGE_FROM_PUBLISH_TO_DRAFT));
|
|
}
|
|
break;
|
|
|
|
case EXPIRED:
|
|
log.warn("Attempt to change status from EXPIRED for Call ID: {} which is not allowed", callId);
|
|
throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.STATUS_CANNOT_BE_CHANGED));
|
|
|
|
case READY_TO_PUBLISH:
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
public CallEntity validatePublishedCall(Long callId, Long hubId) {
|
|
log.info("Validating published call for Call ID: {}, Hub ID: {}", callId, hubId);
|
|
CallEntity callEntity= callRepository
|
|
.findByIdAndStatusAndHubId(callId, CallStatusEnum.PUBLISH.getValue(), hubId);
|
|
if(callEntity==null){
|
|
log.warn("No published call found with Call ID: {} and Hub ID: {}", callId, hubId);
|
|
throw new ResourceNotFoundException(
|
|
Status.NOT_FOUND,
|
|
Translator.toLocale(GepafinConstant.CALL_NOT_PUBLISHED));
|
|
}
|
|
LocalDate currentDate = DateTimeUtil.DateServerToUTC(LocalDateTime.now()).toLocalDate();
|
|
LocalTime currentTime = DateTimeUtil.LocalTimeServerToEurope(LocalTime.now());
|
|
|
|
if (currentDate.isBefore(callEntity.getStartDate().toLocalDate()) ||
|
|
(currentDate.isEqual(callEntity.getStartDate().toLocalDate()) && currentTime.isBefore(callEntity.getStartTime()))) {
|
|
log.warn("Call ID: {} has not started yet. Current time is before start time.", callId);
|
|
throw new CustomValidationException(
|
|
Status.BAD_REQUEST,
|
|
Translator.toLocale(GepafinConstant.CALL_NOT_STARTED_YET)
|
|
);
|
|
}
|
|
|
|
if (currentDate.isAfter(callEntity.getEndDate().toLocalDate()) ||
|
|
(currentDate.isEqual(callEntity.getEndDate().toLocalDate()) && currentTime.isAfter(callEntity.getEndTime()))) {
|
|
log.warn("Call ID: {} has already ended. Current time is after end time.", callId);
|
|
throw new CustomValidationException(
|
|
Status.BAD_REQUEST,
|
|
Translator.toLocale(GepafinConstant.CALL_ALREADY_ENDED)
|
|
);
|
|
}
|
|
|
|
return callEntity;
|
|
}
|
|
|
|
public PageableResponseBean<List<CallDetailsResponseBean>> getAllCallsByPagination(HttpServletRequest request,UserEntity user,Long companyId , Boolean onlyPreferredCall, Boolean onlyConfidiCall, CallPageableRequestBean callPageableRequestBean) {
|
|
log.info("Fetching paginated calls for userId={}, companyId={}, onlyPreferredCall={}", user.getId(), companyId, onlyPreferredCall);
|
|
Integer pageNo = null;
|
|
Integer pageLimit = null;
|
|
if (callPageableRequestBean.getGlobalFilters() != null) {
|
|
pageNo = callPageableRequestBean.getGlobalFilters().getPage();
|
|
pageLimit = callPageableRequestBean.getGlobalFilters().getLimit();
|
|
}
|
|
if (pageLimit == null || pageLimit <= 0) {
|
|
pageLimit = GepafinConstant.DEFAULT_PAGE_LIMIT;
|
|
}
|
|
if (pageNo == null || pageNo <= 0) {
|
|
pageNo = GepafinConstant.DEFAULT_PAGE;
|
|
}
|
|
if (Boolean.TRUE.equals(onlyPreferredCall) && companyId == null) {
|
|
throw new CustomValidationException(
|
|
Status.VALIDATION_ERROR,
|
|
Translator.toLocale(GepafinConstant.COMPANY_ID_REQUIRED_FOR_PREFERRED_CALL)
|
|
);
|
|
}
|
|
expirePublishedCalls(request);
|
|
Specification<CallEntity> spec = search(request,user, callPageableRequestBean,onlyConfidiCall);
|
|
Page<CallEntity> entityPage;
|
|
if (Boolean.TRUE.equals(onlyPreferredCall)) {
|
|
log.debug("Filtering calls for preferred by userId={} and companyId={}", user.getId(), companyId);
|
|
validator.validateUserWithCompany(request, companyId);
|
|
UserWithCompanyEntity userWithCompanyEntity = companyService.getUserWithCompany(user.getId(), companyId);
|
|
List<BeneficiaryPreferredCallEntity> preferredCalls = beneficiaryPreferredCallRepository
|
|
.findByUserIdAndUserWithCompanyIdAndIsDeletedFalse(user.getId(), userWithCompanyEntity.getId());
|
|
List<Long> preferredCallIds = preferredCalls.stream()
|
|
.map(BeneficiaryPreferredCallEntity::getCallId)
|
|
.collect(Collectors.toList());
|
|
|
|
// Add preferredCallIds filtering to the specification
|
|
spec = spec.and((root, query, criteriaBuilder) ->
|
|
criteriaBuilder.and(
|
|
root.get(GepafinConstant.ID).in(preferredCallIds),
|
|
criteriaBuilder.isTrue(root.get("confidi"))
|
|
)
|
|
);
|
|
}
|
|
entityPage = callRepository.findAll(spec, PageRequest.of(pageNo - 1, pageLimit));
|
|
List<Long> callIds=new ArrayList<>();
|
|
if(entityPage!=null && entityPage.getContent()!=null && Boolean.FALSE.equals(entityPage.getContent().isEmpty())) {
|
|
callIds = entityPage.getContent().stream().map(CallEntity::getId).collect(Collectors.toList());
|
|
}
|
|
Map<String, BeneficiaryPreferredCallEntity> preferredCallsMap =
|
|
getBeneficiaryPreferredCallsForUser(request,user, callIds, companyId);
|
|
|
|
List<CallDetailsResponseBean> callDetailsResponseBeans = entityPage.getContent().stream()
|
|
.map(callEntity -> {
|
|
CallDetailsResponseBean responseBean = convertToCallDetailsResponseBean(callEntity);
|
|
String key = user.getId() + "_" + callEntity.getId();
|
|
BeneficiaryPreferredCallEntity preferredCall = preferredCallsMap.get(key);
|
|
Long preferredId = preferredCall != null ? preferredCall.getId() : null;
|
|
responseBean.setPreferredCallId(preferredId);
|
|
|
|
return responseBean;
|
|
})
|
|
.collect(Collectors.toList());
|
|
|
|
|
|
PageableResponseBean<List<CallDetailsResponseBean>> pageableResponseBean = new PageableResponseBean<>();
|
|
pageableResponseBean.setBody(callDetailsResponseBeans);
|
|
pageableResponseBean.setCurrentPage(entityPage.getNumber() + 1); // Page numbers typically start from 0, so add 1 for user-friendly indexing
|
|
pageableResponseBean.setTotalPages(entityPage.getTotalPages());
|
|
pageableResponseBean.setTotalRecords(entityPage.getTotalElements());
|
|
pageableResponseBean.setPageSize(entityPage.getSize());
|
|
|
|
return pageableResponseBean;
|
|
}
|
|
|
|
public Specification<CallEntity> search(HttpServletRequest request,UserEntity userEntity, CallPageableRequestBean callPageableRequestBean,Boolean onlyConfidiCall) {
|
|
return (root, query, criteriaBuilder) -> {
|
|
|
|
List<Predicate> predicates = getPredicates(request,callPageableRequestBean, criteriaBuilder, root, userEntity,onlyConfidiCall);
|
|
SortBy sortBy = new SortBy(GepafinConstant.CREATED_DATE, true);
|
|
|
|
if (callPageableRequestBean.getGlobalFilters() != null
|
|
&& callPageableRequestBean.getGlobalFilters().getSortBy() != null &&
|
|
callPageableRequestBean.getGlobalFilters().getSortBy().getColumnName() != null && Boolean.FALSE.equals(
|
|
isEmpty(callPageableRequestBean.getGlobalFilters().getSortBy().getColumnName()))) {
|
|
sortBy.setColumnName(callPageableRequestBean.getGlobalFilters().getSortBy().getColumnName());
|
|
sortBy.setSortDesc(true);
|
|
if (callPageableRequestBean.getGlobalFilters().getSortBy().getSortDesc() != null) {
|
|
sortBy.setSortDesc(callPageableRequestBean.getGlobalFilters().getSortBy().getSortDesc());
|
|
}
|
|
}
|
|
|
|
query.orderBy(criteriaBuilder.desc(root.get(sortBy.getColumnName())));
|
|
if (Boolean.FALSE.equals(sortBy.getSortDesc())) {
|
|
query.orderBy(criteriaBuilder.asc(root.get(sortBy.getColumnName())));
|
|
}
|
|
return query.where(criteriaBuilder.and(predicates.toArray(new Predicate[0]))).getRestriction();
|
|
};
|
|
}
|
|
|
|
|
|
private List<Predicate> getPredicates(HttpServletRequest request,CallPageableRequestBean callPageableRequestBean,
|
|
CriteriaBuilder criteriaBuilder, Root<CallEntity> root, UserEntity userEntity,Boolean onlyConfidiCall) {
|
|
Integer year = null;
|
|
String search = null;
|
|
Map<String, FilterCriteria> filters = new HashMap<>();
|
|
if (callPageableRequestBean.getGlobalFilters() != null) {
|
|
year = callPageableRequestBean.getGlobalFilters().getYear();
|
|
search = callPageableRequestBean.getGlobalFilters().getSearch();
|
|
}
|
|
if (callPageableRequestBean.getFilters() != null) {
|
|
filters = callPageableRequestBean.getFilters();
|
|
}
|
|
List<Predicate> predicates = new ArrayList<>();
|
|
if (year != null && year > 0) {
|
|
int filterYear = callPageableRequestBean.getGlobalFilters().getYear();
|
|
|
|
// Create LocalDateTime boundaries for the start and end of the year
|
|
LocalDateTime startOfYear = LocalDateTime.of(filterYear, 1, 1, 0, 0);
|
|
LocalDateTime endOfYear = LocalDateTime.of(filterYear, 12, 31, 23, 59, 59);
|
|
|
|
// Add the range comparison to filter records within the year
|
|
predicates.add(criteriaBuilder.between(root.get(GepafinConstant.CREATED_DATE), startOfYear, endOfYear));
|
|
|
|
}
|
|
// Search in `title` and `message` (if search term is provided)
|
|
if (search != null && !search.isEmpty()) {
|
|
Predicate descriptionShort = criteriaBuilder.like(
|
|
criteriaBuilder.upper(root.get(GepafinConstant.DESCRIPTION_SHORT)),
|
|
"%" + search.toUpperCase() + "%"
|
|
);
|
|
predicates.add(criteriaBuilder.or(descriptionShort));
|
|
|
|
Predicate descriptionLong = criteriaBuilder.like(
|
|
criteriaBuilder.upper(root.get(GepafinConstant.DESCRIPTION_LONG)),
|
|
"%" + search.toUpperCase() + "%"
|
|
);
|
|
predicates.add(criteriaBuilder.or(descriptionLong));
|
|
|
|
Predicate name = criteriaBuilder.like(
|
|
criteriaBuilder.upper(root.get(GepafinConstant.NAME)),
|
|
"%" + search.toUpperCase() + "%"
|
|
);
|
|
predicates.add(criteriaBuilder.or(name));
|
|
|
|
|
|
}
|
|
|
|
// Filter by `status` (if status list is provided)
|
|
if (callPageableRequestBean.getStatus() != null && !callPageableRequestBean.getStatus().isEmpty()) {
|
|
List<String> statusValues = callPageableRequestBean.getStatus().stream()
|
|
.map(CallStatusEnum::name) // Convert enum to string
|
|
.toList();
|
|
predicates.add(root.get(GepafinConstant.STATUS).in(statusValues));
|
|
}
|
|
applyFilters(root, criteriaBuilder, predicates, filters);
|
|
Boolean isConfidi =onlyConfidiCall;
|
|
|
|
if (validator.checkIsConfidi()) {
|
|
|
|
if (isConfidi == null || isConfidi.equals(Boolean.FALSE)) {
|
|
// Ensure no records are returned
|
|
return List.of(criteriaBuilder.disjunction());
|
|
}
|
|
|
|
if (isConfidi.equals(Boolean.TRUE)) {
|
|
predicates.add(criteriaBuilder.isTrue(root.get("confidi")));
|
|
}
|
|
} else if (Boolean.TRUE.equals(validator.checkIsBeneficiary())) {
|
|
predicates.add(criteriaBuilder.isFalse(root.get("confidi")));
|
|
} else if( Boolean.FALSE.equals(validator.checkIsConfidi()) && isConfidi!=null){
|
|
if (isConfidi.equals(Boolean.TRUE)) {
|
|
predicates.add(criteriaBuilder.isTrue(root.get("confidi")));
|
|
}
|
|
if (isConfidi.equals(Boolean.FALSE)) {
|
|
predicates.add(criteriaBuilder.isFalse(root.get("confidi")));
|
|
}
|
|
}
|
|
|
|
predicates.add(criteriaBuilder.equal(root.get(GepafinConstant.HUB).get(GepafinConstant.ID), userEntity.getHub().getId()));
|
|
|
|
return predicates;
|
|
|
|
}
|
|
|
|
public void expirePublishedCalls(HttpServletRequest request) {
|
|
|
|
|
|
LocalDate currentDate = DateTimeUtil.DateServerToUTC(LocalDateTime.now()).toLocalDate();
|
|
LocalTime currentTime = DateTimeUtil.LocalTimeServerToEurope(LocalTime.now());
|
|
|
|
log.info("Checking for expired published calls at date={}, time={}", currentDate, currentTime);
|
|
|
|
List<CallEntity> expirdedCallList = callRepository.findExpiredCallsWhichIsPublished(CallStatusEnum.PUBLISH.getValue(), currentDate, currentTime);
|
|
|
|
if (!expirdedCallList.isEmpty()) {
|
|
|
|
loggingUtil.logUserAction(UserActionRequest.builder()
|
|
.request(request)
|
|
.actionType(UserActionLogsEnum.UPDATE)
|
|
.actionContext(UserActionContextEnum.UPDATE_EXPIRED_CALL)
|
|
.build());
|
|
for (CallEntity call : expirdedCallList) {
|
|
CallEntity oldCallEntity = Utils.getClonedEntityForData(call); // Clone before modification
|
|
call.setStatus(CallStatusEnum.EXPIRED.getValue());
|
|
|
|
// Add version history log
|
|
loggingUtil.addVersionHistory(VersionHistoryRequest.builder()
|
|
.request(request)
|
|
.actionType(VersionActionTypeEnum.UPDATE)
|
|
.oldData(oldCallEntity)
|
|
.newData(call)
|
|
.build());
|
|
}
|
|
callRepository.saveAll(expirdedCallList); // Save all modified calls at once
|
|
}
|
|
}
|
|
private void applyFilters(Root<?> root, CriteriaBuilder criteriaBuilder, List<Predicate> predicates, Map<String, FilterCriteria> filters) {
|
|
if (Boolean.FALSE.equals(filters.isEmpty())) {
|
|
for (Map.Entry<String, FilterCriteria> entry : filters.entrySet()) {
|
|
String fieldName = entry.getKey();
|
|
FilterCriteria filterCriteria = entry.getValue();
|
|
Object value = filterCriteria.getValue();
|
|
MatchModeEnum matchMode = filterCriteria.getMatchMode();
|
|
|
|
if (value != null && matchMode != null) {
|
|
Path<?> fieldPath = getFieldPath(root, fieldName);
|
|
if (fieldPath != null) {
|
|
applyStringFilter(fieldPath, criteriaBuilder, predicates, value, matchMode);
|
|
applyNumberFilter(fieldPath, criteriaBuilder, predicates, value, matchMode);
|
|
applyDateFilter(fieldPath, criteriaBuilder, predicates, value, matchMode,root);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private void applyStringFilter(Path<?> fieldPath, CriteriaBuilder criteriaBuilder, List<Predicate> predicates, Object value, MatchModeEnum matchMode) {
|
|
if (value instanceof String) {
|
|
String valueStr = (String) value;
|
|
if (fieldPath.getJavaType().equals(String.class)) {
|
|
MatchModeEnum mode = MatchModeEnum.fromObject(matchMode.getValue());
|
|
switch (mode) {
|
|
case CONTAINS ->
|
|
predicates.add(criteriaBuilder.like(criteriaBuilder.lower(fieldPath.as(String.class)), "%" + valueStr.toLowerCase() + "%"));
|
|
case EQUALS -> predicates.add(criteriaBuilder.equal(fieldPath, valueStr));
|
|
case STARTSWITH ->
|
|
predicates.add(criteriaBuilder.like(criteriaBuilder.lower(fieldPath.as(String.class)), valueStr.toLowerCase() + "%"));
|
|
case ENDSWITH ->
|
|
predicates.add(criteriaBuilder.like(criteriaBuilder.lower(fieldPath.as(String.class)), "%" + valueStr.toLowerCase()));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private void applyNumberFilter(Path<?> fieldPath, CriteriaBuilder criteriaBuilder, List<Predicate> predicates, Object value, MatchModeEnum matchMode) {
|
|
if (Number.class.isAssignableFrom(fieldPath.getJavaType())) {
|
|
Number numberValue = null;
|
|
if (value instanceof Number) {
|
|
numberValue = (Number) value;
|
|
}
|
|
MatchModeEnum mode = MatchModeEnum.fromObject(matchMode.getValue());
|
|
switch (mode) {
|
|
case EQUALS -> predicates.add(criteriaBuilder.equal(fieldPath, numberValue));
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
private void applyDateFilter(Path<?> fieldPath, CriteriaBuilder criteriaBuilder, List<Predicate> predicates, Object value, MatchModeEnum matchMode, Root<?> root) {
|
|
if (fieldPath.getJavaType().equals(LocalDateTime.class)) {
|
|
// Convert input string: Replace 'T' with space
|
|
String formattedValue = value.toString().replace("T", " ");
|
|
|
|
// Handle timezones and UTC (`Z` or `+HH:mm`)
|
|
if (formattedValue.contains("Z") || formattedValue.matches(".*[+-]\\d{2}:\\d{2}$")) {
|
|
OffsetDateTime offsetDateTime = OffsetDateTime.parse(value.toString(), DateTimeFormatter.ISO_OFFSET_DATE_TIME);
|
|
formattedValue = offsetDateTime.toLocalDateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS"));
|
|
}
|
|
|
|
// Check if more than 3 decimal places exist
|
|
if (formattedValue.contains(".")) {
|
|
int dotIndex = formattedValue.indexOf(".");
|
|
if (formattedValue.length() > dotIndex + 4) {
|
|
formattedValue = formattedValue.substring(0, dotIndex + 4); // Keep only 3 decimals
|
|
}
|
|
} else {
|
|
formattedValue += ".000"; // Ensure 3 decimals
|
|
}
|
|
|
|
// Define correct date-time format
|
|
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
|
|
|
|
// Parse the formatted value into LocalDateTime
|
|
LocalDateTime dateTimeValue = LocalDateTime.parse(formattedValue, formatter);
|
|
|
|
// Extract only the date portion
|
|
LocalDate dateValue = dateTimeValue.toLocalDate();
|
|
|
|
// Convert database field to LocalDate for date-only comparison
|
|
Expression<LocalDate> dateField = criteriaBuilder.function("DATE", LocalDate.class, fieldPath);
|
|
|
|
MatchModeEnum mode = MatchModeEnum.fromObject(matchMode.getValue());
|
|
|
|
switch (mode) {
|
|
case DATEIS -> predicates.add(criteriaBuilder.equal(dateField, dateValue));
|
|
case DATEISNOT -> predicates.add(criteriaBuilder.notEqual(dateField, dateValue));
|
|
case BEFORE -> predicates.add(criteriaBuilder.lessThan(fieldPath.as(Timestamp.class), Timestamp.valueOf(dateTimeValue)));
|
|
case AFTER -> predicates.add(criteriaBuilder.greaterThan(fieldPath.as(Timestamp.class), Timestamp.valueOf(dateTimeValue)));
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
private Path<?> getFieldPath(Root<?> root, String fieldName) {
|
|
try {
|
|
return switch (fieldName) {
|
|
|
|
case GepafinConstant.REGION_ID -> {
|
|
// Ensure join is only created if not already present
|
|
Join<?, RegionEntity> regionJoin = root.getJoins().stream()
|
|
.filter(j -> j.getAttribute().getName().equals("region"))
|
|
.findFirst()
|
|
.map(j -> (Join<?, RegionEntity>) j)
|
|
.orElseGet(() -> root.join("region", JoinType.LEFT));
|
|
|
|
yield regionJoin.get("id");
|
|
}
|
|
|
|
default -> root.get(fieldName);
|
|
};
|
|
} catch (IllegalArgumentException e) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
|
|
public CallResponse createCallStep2EvaluationV2(CallEntity callEntity, CreateCallRequestStep2EvaluationV2 createCallRequest, UserEntity user) {
|
|
log.info("Starting Step 2 Evaluation (V2) for Call ID={}, User ID={}", callEntity.getId(), user.getId());
|
|
convertToDocumentEntities(createCallRequest.getDocs(), callEntity.getId(), DocumentTypeEnum.DOCUMENT);
|
|
|
|
convertToDocumentEntities(createCallRequest.getImages(), callEntity.getId(), DocumentTypeEnum.IMAGES);
|
|
|
|
CallResponse createCallResponseBean = getCallResponseBean(callEntity);
|
|
createCallResponseBean.setCurrentStep(GepafinConstant.EVALUATION_V2_STEP_2);
|
|
return createCallResponseBean;
|
|
}
|
|
private Specification<CallEntity> buildCallSpecification(HttpServletRequest request, UserEntity user, Long companyId, Boolean onlyPreferredCall, Boolean onlyConfidiCall, List<String> callStatusList) {
|
|
return (root, query, criteriaBuilder) -> {
|
|
List<Predicate> predicates = new ArrayList<>();
|
|
predicates.add(root.get("status").in(callStatusList));
|
|
|
|
if (Boolean.TRUE.equals(onlyPreferredCall)) {
|
|
validator.validateUserWithCompany(request, companyId);
|
|
UserWithCompanyEntity userWithCompanyEntity = companyService.getUserWithCompany(user.getId(), companyId);
|
|
List<BeneficiaryPreferredCallEntity> preferredCalls = beneficiaryPreferredCallRepository
|
|
.findByUserIdAndUserWithCompanyIdAndIsDeletedFalse(user.getId(), userWithCompanyEntity.getId());
|
|
List<Long> preferredCallIds = preferredCalls.stream()
|
|
.map(BeneficiaryPreferredCallEntity::getCallId)
|
|
.collect(Collectors.toList());
|
|
|
|
predicates.add(root.get("id").in(preferredCallIds));
|
|
} else {
|
|
predicates.add(criteriaBuilder.equal(root.get("hub").get("id"), user.getHub().getId()));
|
|
}
|
|
|
|
if (validator.checkIsConfidi()) {
|
|
if (onlyConfidiCall==null || Boolean.FALSE.equals(onlyConfidiCall)) {
|
|
return criteriaBuilder.disjunction(); // Returns an empty predicate (no results)
|
|
}
|
|
|
|
if (onlyConfidiCall!=null && Boolean.TRUE.equals(onlyConfidiCall)) {
|
|
predicates.add(criteriaBuilder.isTrue(root.get("confidi")));
|
|
}
|
|
} else if (Boolean.TRUE.equals(validator.checkIsBeneficiary())) {
|
|
predicates.add(criteriaBuilder.isFalse(root.get("confidi")));
|
|
} else {
|
|
if(onlyConfidiCall!=null) {
|
|
if (Boolean.TRUE.equals(onlyConfidiCall)) {
|
|
predicates.add(criteriaBuilder.isTrue(root.get("confidi")));
|
|
}
|
|
if (Boolean.FALSE.equals(onlyConfidiCall)) {
|
|
predicates.add(criteriaBuilder.isFalse(root.get("confidi")));
|
|
}
|
|
}
|
|
}
|
|
|
|
return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
|
|
};
|
|
}
|
|
}
|