package net.gepafin.tendermanagement.dao; import net.gepafin.tendermanagement.config.Translator; import net.gepafin.tendermanagement.constants.GepafinConstant; import net.gepafin.tendermanagement.entities.*; import net.gepafin.tendermanagement.enums.ApplicationStatusTypeEnum; import net.gepafin.tendermanagement.enums.RoleStatusEnum; import net.gepafin.tendermanagement.model.request.ApplicationFormFieldRequestBean; import net.gepafin.tendermanagement.model.request.ApplicationRequest; import net.gepafin.tendermanagement.model.request.ApplicationRequestBean; import net.gepafin.tendermanagement.model.response.*; import net.gepafin.tendermanagement.repositories.ApplicationFormFieldRepository; import net.gepafin.tendermanagement.repositories.ApplicationFormRepository; import net.gepafin.tendermanagement.repositories.ApplicationRepository; import net.gepafin.tendermanagement.service.CallService; import net.gepafin.tendermanagement.service.FormService; import net.gepafin.tendermanagement.util.DateTimeUtil; import net.gepafin.tendermanagement.util.Utils; import net.gepafin.tendermanagement.web.rest.api.errors.CustomValidationException; import net.gepafin.tendermanagement.web.rest.api.errors.ResourceNotFoundException; import net.gepafin.tendermanagement.web.rest.api.errors.Status; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.time.LocalDateTime; import java.util.*; import java.util.stream.Collectors; @Component public class ApplicationDao { private final Logger log = LoggerFactory.getLogger(ApplicationDao.class); @Autowired private CallService callService; @Autowired private ApplicationRepository applicationRepository; @Autowired private ApplicationFormRepository applicationFormRepository; @Autowired private ApplicationFormFieldRepository applicationFormFieldRepository; @Autowired private FormService formService; public ApplicationResponseBean createApplication(ApplicationRequestBean applicationRequestBean, UserEntity userEntity, Long formId,Long applicationId) { FormEntity formEntity = formService.validateForm(formId); CallEntity call = callService.validateCall(formEntity.getCall().getId()); ApplicationEntity applicationEntity = validateApplication(applicationId); formService.validateFormField(applicationRequestBean.getFormFields(),applicationEntity,formEntity); ApplicationFormEntity applicationFormEntity = getApplicationFormOrCreate(formEntity, applicationEntity); createOrUpdateMultipleFormFields(applicationRequestBean.getFormFields(), applicationFormEntity); return getApplicationById(applicationEntity.getId(),formEntity.getId()); } public ApplicationFormEntity saveApplicationFormEntity(ApplicationFormEntity applicationFormEntity) { ApplicationFormEntity applicationFormEntity1 = applicationFormRepository.save(applicationFormEntity); return applicationFormEntity1; } public void validateFormId(FormEntity formEntity, CallEntity callEntity) { if (Boolean.FALSE.equals(formEntity.getId().equals(callEntity.getInitialForm()))) { throw new CustomValidationException(Status.BAD_REQUEST,Translator.toLocale(GepafinConstant.FORM_ID_DOES_NOT_MACTHES)); } } public ApplicationFormEntity createApplicationFormEntity(ApplicationEntity application, FormEntity formEntity) { ApplicationFormEntity applicationFormEntity = new ApplicationFormEntity(); applicationFormEntity.setApplication(application); applicationFormEntity.setForm(formEntity); applicationFormEntity = saveApplicationFormEntity(applicationFormEntity); return applicationFormEntity; } public ApplicationEntity createApplicationEntity(UserEntity user, CallEntity call) { ApplicationEntity entity = new ApplicationEntity(); entity.setUser(user); entity.setCall(call); entity.setIsDeleted(false); entity.setStatus(ApplicationStatusTypeEnum.DRAFT.getValue()); return entity; } public ApplicationResponseBean getApplicationById(Long id,Long formId) { log.info("Fetching application with ID: {}", id); ApplicationEntity applicationEntity = validateApplication(id); ApplicationFormEntity applicationFormEntity = applicationFormRepository.findByApplicationIdAndFormId(applicationEntity.getId(),formId); List applicationFormFieldResponseBeans=new ArrayList<>(); ApplicationFormFieldResponseBean applicationFormFieldResponseBeans1=null; List applicationFormFieldEntities = applicationFormFieldRepository.findByApplicationFormId(applicationFormEntity.getId()); for(ApplicationFormFieldEntity applicationFormFieldEntity:applicationFormFieldEntities) { applicationFormFieldResponseBeans1 = convertApplicationFormFieldEntityToApplicationFormFieldResponseBean(applicationFormFieldEntity, applicationFormEntity.getId()); applicationFormFieldResponseBeans.add(applicationFormFieldResponseBeans1); } ApplicationResponseBean applicationResponseBean= convertApplicationEntityToApplicationResponseBean(applicationEntity); applicationResponseBean.setFormFields(applicationFormFieldResponseBeans); applicationResponseBean.setCurrentFormId(formId); return applicationResponseBean; } public void deleteById(Long id) { log.info("Deleting application with ID: {}", id); ApplicationEntity applicationEntity= validateApplication(id); applicationEntity.setIsDeleted(true); applicationEntity=saveApplicationEntity(applicationEntity); log.info("Application deleted with ID: {}", id); } public List getAllApplications(UserEntity userEntity, Long callId) { RoleStatusEnum roleStatus = RoleStatusEnum.valueOf(userEntity.getRoleEntity().getRoleType()); boolean isBeneficiary = RoleStatusEnum.ROLE_BENEFICIARY.equals(roleStatus); log.info("Fetching applications for RoleType: {}", roleStatus); List applicationResponses = new ArrayList<>(); if (callId != null) { // Fetch based on callId and user if role is BENEFICIARY, otherwise fetch all for the call log.info("Fetching applications for callId: {}", callId); CallEntity call = callService.validateCall(callId); // Use a single method to handle both conditions for consistency List applicationEntities = isBeneficiary ? applicationRepository.findByUserIdAndCallIdAndIsDeletedFalse(userEntity.getId(), call.getId()) .map(List::of) // Convert Optional to a List of one element .orElse(List.of()) // If not present, return an empty list : applicationRepository.findByCallIdAndIsDeletedFalse(call.getId()); applicationResponses = applicationEntities.stream() .map(this::getApplicationResponse) .collect(Collectors.toList()); } else { // Fetch all applications for the user if BENEFICIARY, or fetch all applications in general List applicationEntities = isBeneficiary ? applicationRepository.findByUserIdAndIsDeletedFalse(userEntity.getId()) : applicationRepository.findByIsDeletedFalse(); applicationResponses = applicationEntities.stream() .map(this::getApplicationResponse) .collect(Collectors.toList()); } return applicationResponses; } private ApplicationResponse getApplicationResponse(ApplicationEntity applicationEntity) { ApplicationResponse responseBean = new ApplicationResponse(); responseBean.setId(applicationEntity.getId()); responseBean.setCallId(applicationEntity.getCall().getId()); responseBean.setSubmissionDate(applicationEntity.getSubmissionDate()); responseBean.setStatus(applicationEntity.getStatus()); responseBean.setComments(applicationEntity.getComments()); return responseBean; } public ApplicationEntity validateApplication(Long id) { ApplicationEntity applicationEntity= applicationRepository.findById(id).orElseThrow(() ->new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.APPLICATION_NOT_FOUND_MSG))); return applicationEntity; } private ApplicationResponseBean convertApplicationEntityToApplicationResponseBean(ApplicationEntity entity) { ApplicationResponseBean response = new ApplicationResponseBean(); response.setId(entity.getId()); response.setSubmissionDate(entity.getSubmissionDate()); response.setStatus(entity.getStatus()); response.setComments(entity.getComments()); response.setCallId(entity.getCall().getId()); response.setCreatedDate(entity.getCreatedDate()); response.setUpdatedDate(entity.getUpdatedDate()); return response; } private ApplicationFormEntity getApplicationFormOrCreate(FormEntity formEntity, ApplicationEntity applicationEntity) { ApplicationFormEntity applicationFormEntity = applicationFormRepository.findByApplicationIdAndFormId(applicationEntity.getId(), formEntity.getId()); if(applicationFormEntity == null){ applicationFormEntity = createApplicationFormEntity(applicationEntity, formEntity); } return applicationFormEntity; } public List createOrUpdateMultipleFormFields(List formFieldResponseBeans, ApplicationFormEntity applicationFormEntity) { List existingFields = applicationFormFieldRepository.findByApplicationFormId(applicationFormEntity.getId()); List applicationFormFieldEntity = formFieldResponseBeans.stream() .map(requestBean -> createOrUpdateApplicationFormField(requestBean, applicationFormEntity,existingFields)) .collect(Collectors.toList()); return applicationFormFieldEntity; } public ApplicationFormFieldEntity createOrUpdateApplicationFormField(ApplicationFormFieldRequestBean applicationFormFieldRequestBean, ApplicationFormEntity applicationFormEntity,List applicationFormFieldEntities ) { ApplicationFormFieldEntity applicationFormFieldEntity=null; if(applicationFormFieldEntities==null || applicationFormFieldEntities.isEmpty()){ applicationFormFieldEntity = new ApplicationFormFieldEntity(); applicationFormFieldEntity.setApplicationForm(applicationFormEntity); }else { for (ApplicationFormFieldEntity applicationFormFieldEntity1 : applicationFormFieldEntities) { if (applicationFormFieldEntity1.getFieldId().equals(applicationFormFieldRequestBean.getFieldId())) { applicationFormFieldEntity = applicationFormFieldEntity1; break; } else { applicationFormFieldEntity = new ApplicationFormFieldEntity(); applicationFormFieldEntity.setApplicationForm(applicationFormEntity); } } } Utils.setIfUpdated(applicationFormFieldEntity::getFieldId, applicationFormFieldEntity::setFieldId, applicationFormFieldRequestBean.getFieldId()); Utils.setIfUpdated(applicationFormFieldEntity::getFieldValue, applicationFormFieldEntity::setFieldValue, applicationFormFieldRequestBean.getFieldValue()); return applicationFormFieldRepository.save(applicationFormFieldEntity); } public ApplicationFormFieldEntity validateApplicationFormField(Long applicationFormFieldId) { Optional applicationFormFieldEntity = applicationFormFieldRepository.findById(applicationFormFieldId); if (applicationFormFieldEntity.isEmpty()) { throw new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.APPLICATION_FORM_FIELD_NOT_FOUND)); } return applicationFormFieldEntity.get(); } public List saveApplicationFormFieldEntities(List applicationFormFieldEntities) { List applicationFormFieldEntities1 = applicationFormFieldRepository.saveAll(applicationFormFieldEntities); return applicationFormFieldEntities1; } public List convertApplicationFormFieldEntitiesToApplicationFormFieldResponseBeans(List applicationFormFieldEntities, Long applicationFormId) { return applicationFormFieldEntities.stream() .map(requestBean -> convertApplicationFormFieldEntityToApplicationFormFieldResponseBean(requestBean, applicationFormId)) .collect(Collectors.toList()); } public ApplicationFormFieldResponseBean convertApplicationFormFieldEntityToApplicationFormFieldResponseBean(ApplicationFormFieldEntity applicationFormFieldEntity, Long applicationFormId) { ApplicationFormFieldResponseBean applicationFormFieldResponseBean = new ApplicationFormFieldResponseBean(); applicationFormFieldResponseBean.setApplicationFormId(applicationFormId); applicationFormFieldResponseBean.setFieldId(applicationFormFieldEntity.getFieldId()); applicationFormFieldResponseBean.setFieldValue(applicationFormFieldEntity.getFieldValue()); applicationFormFieldResponseBean.setId(applicationFormFieldEntity.getId()); applicationFormFieldResponseBean.setCreatedDate(applicationFormFieldEntity.getCreatedDate()); applicationFormFieldResponseBean.setUpdatedDate(applicationFormFieldEntity.getUpdatedDate()); return applicationFormFieldResponseBean; } public ApplicationEntity saveApplicationEntity(ApplicationEntity application){ ApplicationEntity applicationEntity=applicationRepository.save(application); return applicationEntity; } public ApplicationGetResponseBean getApplicationByFormId( Long applicationId,Long formId, UserEntity userEntity) { List formApplicationResponses = new ArrayList<>(); List formEntities = new ArrayList<>(); ApplicationEntity applicationEntity = applicationRepository.findById(applicationId) .orElseThrow(() -> new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.APPLICATION_NOT_FOUND_MSG))); if (formId != null) { FormEntity formEntity = formService.validateForm(formId); Optional application = applicationRepository.findByUserIdAndCallIdAndIsDeletedFalse(userEntity.getId(), formEntity.getCall().getId()); applicationEntity=application.get(); formEntities.add(formEntity); addFormApplication(formEntity, applicationEntity, formApplicationResponses); } else { List applicationFormEntities = applicationFormRepository.findByApplicationId(applicationEntity.getId()); for (ApplicationFormEntity applicationFormEntity : applicationFormEntities) { FormEntity form = formService.validateForm(applicationFormEntity.getForm().getId()); formEntities.add(form); addFormApplication(form, applicationEntity, formApplicationResponses); } } return createApplicationGetResponseBean(applicationEntity, formEntities, formApplicationResponses); } private void addFormApplication(FormEntity formEntity, ApplicationEntity applicationEntity, List formApplicationResponses) { FormApplicationResponse formApplicationResponse = processForm(formEntity, applicationEntity); if(formApplicationResponse.getContent() != null && formApplicationResponse.getFormFields() != null) { formApplicationResponses.add(formApplicationResponse); } } public FormApplicationResponse processForm(FormEntity formEntity, ApplicationEntity applicationEntity) { FormApplicationResponse formApplicationResponse = createFormApplicationResponse(formEntity); ApplicationFormEntity applicationFormEntity = applicationFormRepository.findByApplicationIdAndFormId(applicationEntity.getId(), formEntity.getId()); if(applicationFormEntity!=null) { List applicationFormFieldEntities = applicationFormFieldRepository.findByApplicationFormId(applicationFormEntity.getId()); // formApplicationResponse = createFormApplicationResponse(formEntity); List applicationFormFieldResponseBeans = convertApplicationFormFieldEntitiesToApplicationFormFieldResponseBeans(applicationFormFieldEntities, applicationFormEntity.getId()); formApplicationResponse.setFormFields(applicationFormFieldResponseBeans); } return formApplicationResponse; } private ApplicationGetResponseBean createApplicationGetResponseBean(ApplicationEntity applicationEntity, List formEntities, List formApplicationResponses) { ApplicationGetResponseBean applicationGetResponseBean =createApplicationGetResponseBean(applicationEntity); applicationGetResponseBean.setForm(formApplicationResponses); return applicationGetResponseBean; } private ApplicationGetResponseBean createApplicationGetResponseBean(ApplicationEntity applicationEntity) { ApplicationGetResponseBean applicationGetResponseBean = new ApplicationGetResponseBean(); applicationGetResponseBean.setId(applicationEntity.getId()); applicationGetResponseBean.setStatus(applicationEntity.getStatus()); applicationGetResponseBean.setComments(applicationEntity.getComments()); applicationGetResponseBean.setSubmissionDate(applicationEntity.getSubmissionDate()); return applicationGetResponseBean; } private FormApplicationResponse createFormApplicationResponse(FormEntity formEntity) { FormApplicationResponse formApplicationResponse=new FormApplicationResponse(); formApplicationResponse.setId(formEntity.getId()); formApplicationResponse.setLabel(formEntity.getLabel()); formApplicationResponse.setCallId(formEntity.getCall().getId()); formApplicationResponse.setContent(Utils.convertJsonStringToList(formEntity.getContent(), ContentResponseBean.class)); return formApplicationResponse; } public ApplicationResponse createApplicationByCallId(ApplicationRequest applicationRequest,Long callId,UserEntity userEntity){ CallEntity call=callService.validateCall(callId); checkIfApplicationExists(call,userEntity); ApplicationEntity applicationEntity=createApplicationEntity(userEntity,call); applicationEntity.setComments(applicationRequest.getComments()); applicationEntity=saveApplicationEntity(applicationEntity); ApplicationResponse applicationResponse=getApplicationResponse(applicationEntity); return applicationResponse; } public void checkIfApplicationExists(CallEntity call,UserEntity userEntity){ Optional applicationEntity=applicationRepository.findByUserIdAndCallIdAndIsDeletedFalse(userEntity.getId(),call.getId()); if(applicationEntity.isPresent()){ throw new CustomValidationException(Status.BAD_REQUEST,Translator.toLocale(GepafinConstant.APPLICATION_ALREADY_EXISTS)); } } public ApplicationEntity getApplicationByCallAndUser(CallEntity call, UserEntity userEntity) { return applicationRepository.findByUserIdAndCallIdAndIsDeletedFalse(userEntity.getId(), call.getId()) .orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.APPLICATION_NOT_FOUND_MSG))); } public void updateApplicationStatus(Long applicationId, ApplicationStatusTypeEnum status) { ApplicationEntity applicationEntity = validateApplication(applicationId); applicationEntity.setStatus(status.getValue()); if(status.equals(ApplicationStatusTypeEnum.SUBMIT)) { applicationEntity.setSubmissionDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); } saveApplicationEntity(applicationEntity); } }