diff --git a/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java b/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java index ce0f53b5..8fa5ab0d 100644 --- a/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java +++ b/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java @@ -108,5 +108,25 @@ public class GepafinConstant { public static final String FLOW_FETCHED_SUCCESSFULLY="flow.fetched.successfully"; public static final String FLOW_ALREADY_EXISTS="flow.already.exists"; public static final String FLOW_REQUEST_NOT_PROPER="flow.request.not.complete"; + public static final String APPLICATION_CREATED_SUCCESS_MSG = "application.created.success"; + public static final String APPLICATION_UPDATED_SUCCESS_MSG = "application.updated.success"; + public static final String DELETE_APPLICATION_SUCCESS_MSG = "application.deleted.success"; + public static final String GET_APPLICATION_SUCCESS_MSG = "application.get.success"; + public static final String APPLICATION_NOT_FOUND_MSG = "application.not.found"; + public static final String APPLICATION_FORM_FIELD_NOT_FOUND="application.form.field.not.found"; + public static final String FORM_ID_DOES_NOT_MACTHES="Form.not.matches.to.call.initial.form"; + public static final String VALIDATION_FIELD_REQUIRED = "validation.field.required"; + public static final String VALIDATION_FIELD_MIN_LENGTH = "validation.field.min_length"; + public static final String VALIDATION_FIELD_MAX_LENGTH = "validation.field.max_length"; + public static final String VALIDATION_FIELD_PATTERN = "validation.field.pattern"; + public static final String VALIDATION_FIELD_NOT_NULL = "validation.field.not_null"; + public static final String VALIDATION_FIELD_NOT_EMPTY = "validation.field.not_empty"; + public static final String APPLICATION_ALREADY_EXISTS="application.already.exists"; + // public static final String NEXT_FORM_NOT_FOUND = "next.form.not.found"; + // public static final String PREVIOUS_FORM_NOT_FOUND = "previous.form.not.found"; + public static final String CURRENT_FORM_INCOMPLETE = "current.form.incomplete"; + + + public static final String FLOW_NOT_FOUND = "flow.not.found"; } diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java new file mode 100644 index 00000000..f1a99e27 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java @@ -0,0 +1,321 @@ +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.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; + + @Autowired + private FormDao formDao; + + public ApplicationResponseBean createApplication(ApplicationRequestBean applicationRequestBean, UserEntity userEntity, Long formId) { + FormEntity formEntity = formService.validateForm(formId); + CallEntity call = callService.validateCall(formEntity.getCall().getId()); + ApplicationEntity applicationEntity = getApplicationOrCreate(userEntity, call, formEntity); + 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); + List applicationFormEntities = applicationFormRepository.findByApplicationId(applicationEntity.getId()); + List applicationFormFieldResponseBeans=new ArrayList<>(); + ApplicationFormFieldResponseBean applicationFormFieldResponseBeans1=null; + for (ApplicationFormEntity applicationFormEntity:applicationFormEntities){ + 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) { + log.info("Fetching all applications"); + List applicationResponses=new ArrayList<>(); + List applicationEntities = applicationRepository.findByUserIdAndIsDeletedFalse(userEntity.getId()); + for(ApplicationEntity applicationEntity:applicationEntities){ + ApplicationResponse responseBean = getApplicationResponse(applicationEntity); + applicationResponses.add(responseBean); + } + 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; + } + + public ApplicationEntity getApplicationOrCreate(UserEntity userEntity, CallEntity callEntity, FormEntity formEntity) { + ApplicationEntity applicationEntity = applicationRepository.findByUserIdAndCallIdAndIsDeletedFalse(userEntity.getId(), callEntity.getId()).orElse(null); + if (applicationEntity == null) { + validateFormId(formEntity, callEntity); + applicationEntity = createApplicationEntity(userEntity, callEntity); + applicationEntity=saveApplicationEntity(applicationEntity); + } + return applicationEntity; + } + 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 applicationFormFieldEntity = formFieldResponseBeans.stream() + .map(requestBean -> createOrUpdateApplicationFormField(requestBean, applicationFormEntity)) + .collect(Collectors.toList()); + return applicationFormFieldEntity; + } + + public ApplicationFormFieldEntity createOrUpdateApplicationFormField(ApplicationFormFieldRequestBean applicationFormFieldRequestBean, ApplicationFormEntity applicationFormEntity) { + ApplicationFormFieldEntity applicationFormFieldEntity; + if (applicationFormFieldRequestBean.getId() == null || applicationFormFieldRequestBean.getId() == 0) { + applicationFormFieldEntity = new ApplicationFormFieldEntity(); + applicationFormFieldEntity.setApplicationForm(applicationFormEntity); + } else { + applicationFormFieldEntity = validateApplicationFormField(applicationFormFieldRequestBean.getId()); + } + 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); + processForm(formEntity, applicationEntity, formApplicationResponses); + } + else { + List applicationFormEntities = applicationFormRepository.findByApplicationId(applicationEntity.getId()); + for (ApplicationFormEntity applicationFormEntity : applicationFormEntities) { + FormEntity form = formService.validateForm(applicationFormEntity.getForm().getId()); + formEntities.add(form); + processForm(form, applicationEntity, formApplicationResponses); + } + } + + return createApplicationGetResponseBean(applicationEntity, formEntities, formApplicationResponses); + } + + private void processForm(FormEntity formEntity, ApplicationEntity applicationEntity, List formApplicationResponses) { + ApplicationFormEntity applicationFormEntity = applicationFormRepository.findByApplicationIdAndFormId(applicationEntity.getId(), formEntity.getId()); + if(applicationFormEntity!=null) { + List applicationFormFieldEntities = applicationFormFieldRepository.findByApplicationFormId(applicationFormEntity.getId()); + FormApplicationResponse formApplicationResponse = createFormApplicationResponse(formEntity); + List applicationFormFieldResponseBeans = convertApplicationFormFieldEntitiesToApplicationFormFieldResponseBeans(applicationFormFieldEntities, applicationFormEntity.getId()); + + formApplicationResponse.setFormFields(applicationFormFieldResponseBeans); + formApplicationResponses.add(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=saveApplicationEntity(createApplicationEntity(userEntity,call)); + 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); + } +} diff --git a/src/main/java/net/gepafin/tendermanagement/dao/FlowFormDao.java b/src/main/java/net/gepafin/tendermanagement/dao/FlowFormDao.java new file mode 100644 index 00000000..7163f1f6 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/dao/FlowFormDao.java @@ -0,0 +1,255 @@ +package net.gepafin.tendermanagement.dao; + +import java.util.List; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import net.gepafin.tendermanagement.config.Translator; +import net.gepafin.tendermanagement.constants.GepafinConstant; +import net.gepafin.tendermanagement.entities.ApplicationEntity; +import net.gepafin.tendermanagement.entities.ApplicationFormEntity; +import net.gepafin.tendermanagement.entities.ApplicationFormFieldEntity; +import net.gepafin.tendermanagement.entities.FlowDataEntity; +import net.gepafin.tendermanagement.entities.FlowEdgesEntity; +import net.gepafin.tendermanagement.entities.FormEntity; +import net.gepafin.tendermanagement.enums.FormActionEnum; +import net.gepafin.tendermanagement.model.response.NextOrPreviousFormResponse; +import net.gepafin.tendermanagement.repositories.ApplicationFormFieldRepository; +import net.gepafin.tendermanagement.repositories.ApplicationFormRepository; +import net.gepafin.tendermanagement.repositories.FlowDataRepository; +import net.gepafin.tendermanagement.repositories.FlowEdgesRepository; +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; + +@Component +public class FlowFormDao { + + @Autowired + private FlowEdgesRepository flowEdgesRepository; + + @Autowired + private FlowDataRepository flowDataRepository; + + @Autowired + private ApplicationFormFieldRepository applicationFormFieldRepository; + + @Autowired + private ApplicationFormRepository applicationFormRepository; + + +// Long getNextForm(FormEntity currentFormEntity, ApplicationEntity applicationEntity) { +// // vlaidation if next form findout and cuuent from is not fill the give error +// List flowEdgesList = flowEdgesRepository.findBySourceIdAndCallId(currentFormEntity.getId(), applicationEntity.getCall().getId()); +// ApplicationFormEntity applicationFormEntity = applicationFormRepository.findByApplicationIdAndFormId(applicationEntity.getId(), currentFormEntity.getId()); +// if(applicationFormEntity == null) { +// throw new CustomValidationException(Status.VALIDATION_ERROR, +// Translator.toLocale("current form is not fill")); +// } +// if(flowEdgesList.isEmpty()) { +// throw new ResourceNotFoundException(Status.NOT_FOUND, +// Translator.toLocale(GepafinConstant.NEXT_FORM_NOT_FOUND)); +// } else if(flowEdgesList.size() == 1) { +// return flowEdgesList.get(0).getTargetId(); +// } else { +// List nextFormIds = flowEdgesList.stream().map(FlowEdgesEntity::getTargetId).toList(); +// FlowDataEntity flowDataEntity = flowDataRepository.findByFormIdAndCallId(currentFormEntity.getId(), applicationEntity.getCall().getId()); +// +// ApplicationFormFieldEntity applicationFormFieldEntity = applicationFormFieldRepository +// .findByFieldIdAndApplicationFormFormIdAndApplicationFormApplicationId(flowDataEntity.getChoosenField(), +// currentFormEntity.getId(), applicationEntity.getId()).orElseThrow(()-> new ResourceNotFoundException(Status.NOT_FOUND, +// Translator.toLocale(GepafinConstant.NEXT_FORM_NOT_FOUND))); +// +// flowDataEntity = flowDataRepository.findByChoosenValueAndFormIdIn(applicationFormFieldEntity.getFieldValue(), nextFormIds).orElseThrow(()-> new NullPointerException()); +// return flowDataEntity.getFormId(); +// } +// } +// +// +// Long getPreviousForm(FormEntity currentFormEntity, ApplicationEntity applicationEntity) { +// +// // Step 1: Find all edges where the current form is the target (i.e., reverse flow) +// List flowEdgesList = flowEdgesRepository.findByTargetIdAndCallId( +// currentFormEntity.getId(), applicationEntity.getCall().getId()); +// +// if (flowEdgesList.isEmpty()) { +// // If no previous edges are found, return null or handle this case based on your needs +// throw new ResourceNotFoundException(Status.NOT_FOUND, +// Translator.toLocale(GepafinConstant.PREVIOUS_FORM_NOT_FOUND)); +// } +// +// // Step 2: If only one edge exists, return the source (previous) form ID directly have to look into it +// if (flowEdgesList.size() == 1) { +// return flowEdgesList.get(0).getSourceId(); +// } +// List previousFormIds = flowEdgesList.stream().map(FlowEdgesEntity::getSourceId).toList(); +// +// +// // Step 3: Try to find flow data for the current form. If not found, we know it's the last step (or no field filtering is needed). +// List flowDataList = flowDataRepository.findByFormIdInAndCallId( +// previousFormIds, applicationEntity.getCall().getId()); +// +// List fieldValue = flowDataList.stream().map(FlowDataEntity::getChoosenValue).toList(); +// +//// if (flowDataEntity == null || flowDataEntity.getChoosenField() == null) { +//// // If flow data is not found, simply return the first matching previous form +//// return flowEdgesList.get(0).getSourceId(); // You can modify this logic if needed +//// } +// +// // Step 4: Fetch the field value from the application form fields +// Set formList = applicationFormFieldRepository +// .findByFieldValueInAndAndApplicationFormApplicationId( +// fieldValue, applicationEntity.getId()).stream().map(applicationFormFieldEntity->applicationFormFieldEntity.getApplicationForm().getForm()).collect(Collectors.toSet()); +// +// List fieldIds = formList.stream().map(formEntity->getNextForm(formEntity, applicationEntity)).toList(); +// for(Long formId:previousFormIds) { +// fieldIds.contains(formId); +// return formId; +// } +// return null; +//// .orElseThrow(() -> new NullPointerException("Field value not found for the current form and application.")); +// +// +//// // Step 5: Check if there's a matching previous form based on the chosen value +//// FlowDataEntity previousFlowDataEntity = flowDataRepository.findByChoosenValueAndFormIdIn( +//// applicationFormFieldEntity.getFieldValue(), flowEdgesList.stream().map(FlowEdgesEntity::getSourceId).toList()) +//// .orElse(null); // If no matching form is found, return null or the first source form +//// +//// // Step 6: Return the formId of the matching previous form, or the first one if no specific match is found +//// return previousFlowDataEntity != null ? previousFlowDataEntity.getFormId() : flowEdgesList.get(0).getSourceId(); +// } + + + public Long getNextForm(FormEntity currentFormEntity, ApplicationEntity applicationEntity) { + // Validate if the current form has been filled + ApplicationFormEntity applicationFormEntity = applicationFormRepository.findByApplicationIdAndFormId( + applicationEntity.getId(), currentFormEntity.getId()); + + // Retrieve the flow edges for the next forms + List flowEdgesList = flowEdgesRepository.findBySourceIdAndCallId( + currentFormEntity.getId(), applicationEntity.getCall().getId()); + + if (flowEdgesList.isEmpty()) { + return null; +// throw new ResourceNotFoundException(Status.NOT_FOUND, +// Translator.toLocale(GepafinConstant.NEXT_FORM_NOT_FOUND)); + } + + // If only one edge exists, return the target form ID + if (flowEdgesList.size() == 1) { + return flowEdgesList.get(0).getTargetId(); + } + + if (applicationFormEntity == null) { + throw new CustomValidationException(Status.VALIDATION_ERROR, + Translator.toLocale(GepafinConstant.CURRENT_FORM_INCOMPLETE)); + } + + // For multiple edges, find the next form based on the chosen value + List nextFormIds = flowEdgesList.stream() + .map(FlowEdgesEntity::getTargetId) + .toList(); + + // Retrieve the flow data for the current form + FlowDataEntity flowDataEntity = flowDataRepository.findByFormIdAndCallId( + currentFormEntity.getId(), applicationEntity.getCall().getId()); + + // Fetch the application form field related to the chosen field + ApplicationFormFieldEntity applicationFormFieldEntity = applicationFormFieldRepository + .findByFieldIdAndApplicationFormFormIdAndApplicationFormApplicationId( + flowDataEntity.getChoosenField(), currentFormEntity.getId(), applicationEntity.getId()).orElse(null); + + // Find the next form based on the chosen value and return its ID + return flowDataRepository.findByChoosenValueAndFormIdIn( + applicationFormFieldEntity.getFieldValue(), nextFormIds) + .map(FlowDataEntity::getFormId) + .orElse(null); + } + + public Long getPreviousForm(FormEntity currentFormEntity, ApplicationEntity applicationEntity) { + // Retrieve the flow edges for the previous forms + List flowEdgesList = flowEdgesRepository.findByTargetIdAndCallId( + currentFormEntity.getId(), applicationEntity.getCall().getId()); + + if (flowEdgesList.isEmpty()) { + return null; +// throw new ResourceNotFoundException(Status.NOT_FOUND, +// Translator.toLocale(GepafinConstant.PREVIOUS_FORM_NOT_FOUND)); + } + + // If only one edge exists, return the source form ID + if (flowEdgesList.size() == 1) { + return flowEdgesList.get(0).getSourceId(); + } + + // For multiple edges, find the previous form based on the chosen value + List previousFormIds = flowEdgesList.stream() + .map(FlowEdgesEntity::getSourceId) + .toList(); + + // Fetch the flow data based on previous form IDs + List flowDataList = flowDataRepository.findByFormIdInAndCallId( + previousFormIds, applicationEntity.getCall().getId()); + + List chosenValues = flowDataList.stream() + .map(FlowDataEntity::getChoosenValue) + .toList(); + + // Fetch the previous forms based on the chosen field values + Set formList = applicationFormFieldRepository + .findByFieldValueInAndApplicationFormApplicationId(chosenValues, applicationEntity.getId()).stream() + .map(fieldEntity -> fieldEntity.getApplicationForm().getForm()) + .collect(Collectors.toSet()); + + // Find next form IDs recursively for all forms in the formList + List fieldIds = formList.stream() + .map(formEntity -> getNextForm(formEntity, applicationEntity)) + .toList(); + + // Return the first matching previous form ID that corresponds to a next form + return previousFormIds.stream() + .filter(fieldIds::contains) + .findFirst().orElse(null); + } + + public NextOrPreviousFormResponse getnextOrPreviousForm(ApplicationEntity applicationEntity, Long formId, + FormActionEnum action) { + FormEntity fromEntity = null; + if(formId == null) { + NextOrPreviousFormResponse nextOrPreviousFormResponse = new NextOrPreviousFormResponse(); + nextOrPreviousFormResponse.setNextFormId(getDefaultForm(applicationEntity)); + return nextOrPreviousFormResponse; + }else { + fromEntity = Optional + .of(applicationFormRepository.findByApplicationIdAndFormId(applicationEntity.getId(), formId)) + .orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND, + Translator.toLocale(GepafinConstant.FORM_NOT_FOUND))) + .getForm(); + } + + NextOrPreviousFormResponse nextOrPreviousFormResponse = new NextOrPreviousFormResponse(); + if (action.equals(FormActionEnum.NEXT)) { + nextOrPreviousFormResponse.setNextFormId(getNextForm(fromEntity, applicationEntity)); + } else { + nextOrPreviousFormResponse.setPreviousFormId(getPreviousForm(fromEntity, applicationEntity)); + } + return nextOrPreviousFormResponse; + } + + private Long getDefaultForm(ApplicationEntity applicationEntity) { + List applicationFormList = applicationFormRepository.findByApplicationIdOrderByCreatedDateAsc(applicationEntity.getId()); + if(applicationFormList.isEmpty()) { + return applicationEntity.getCall().getInitialForm(); + } + if(applicationFormList.get(applicationFormList.size()-1).getForm().getId().equals(applicationEntity.getCall().getFinalForm())) { + return applicationEntity.getCall().getInitialForm(); + } + return getNextForm(applicationFormList.get(applicationFormList.size()-1).getForm(), applicationEntity); + } + + +} diff --git a/src/main/java/net/gepafin/tendermanagement/dao/FormDao.java b/src/main/java/net/gepafin/tendermanagement/dao/FormDao.java index dd11b579..db91f787 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/FormDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/FormDao.java @@ -2,15 +2,18 @@ package net.gepafin.tendermanagement.dao; import net.gepafin.tendermanagement.config.Translator; import net.gepafin.tendermanagement.constants.GepafinConstant; -import net.gepafin.tendermanagement.entities.CallEntity; -import net.gepafin.tendermanagement.entities.FormEntity; +import net.gepafin.tendermanagement.entities.*; +import net.gepafin.tendermanagement.model.request.ApplicationFormFieldRequestBean; import net.gepafin.tendermanagement.model.request.ContentRequestBean; +import net.gepafin.tendermanagement.model.request.FieldValidatorBean; import net.gepafin.tendermanagement.model.request.FormRequest; import net.gepafin.tendermanagement.model.response.ContentResponseBean; import net.gepafin.tendermanagement.model.response.FormResponseBean; +import net.gepafin.tendermanagement.repositories.ApplicationFormRepository; import net.gepafin.tendermanagement.repositories.FormRepository; import net.gepafin.tendermanagement.service.CallService; import net.gepafin.tendermanagement.util.DateTimeUtil; +import net.gepafin.tendermanagement.util.FieldValidator; import net.gepafin.tendermanagement.util.Utils; import net.gepafin.tendermanagement.web.rest.api.errors.CustomValidationException; import net.gepafin.tendermanagement.web.rest.api.errors.ResourceNotFoundException; @@ -20,6 +23,7 @@ import org.springframework.stereotype.Component; import java.time.LocalDateTime; import java.util.List; +import java.util.Map; import java.util.stream.Collectors; @Component @@ -31,6 +35,9 @@ public class FormDao { @Autowired private CallService callService; + @Autowired + private ApplicationFormRepository applicationFormRepository; + public FormEntity saveFormEntity(FormEntity formEntity){ formEntity=formRepository.save(formEntity); return formEntity; @@ -101,4 +108,37 @@ public class FormDao { public String setContentResponseBean(List contentRequestBeans){ return Utils.convertListToJsonString(contentRequestBeans); } + + public void validateFormField(List applicationFormFieldRequestList, ApplicationEntity applicationEntity, FormEntity formEntity) { + + Map formFieldMap = applicationFormFieldRequestList.stream() + .collect(Collectors.toMap(ApplicationFormFieldRequestBean::getFieldId, ApplicationFormFieldRequestBean::getFieldValue)); + FormResponseBean formResponseBean = convertFormEntityToFormResponseBean(formEntity); + ApplicationFormEntity applicationFormEntity=applicationFormRepository.findByApplicationIdAndFormId(applicationEntity.getId(),formEntity.getId()); + Boolean isApplicationFormExist= getApplicationFormExist(applicationFormEntity); + FieldValidator validator = FieldValidator.create(); + formResponseBean.getContent().forEach(contentResponseBean -> { + String fieldId = contentResponseBean.getId(); + String value = formFieldMap.get(fieldId); + if(value == null && isApplicationFormExist) { + return; + } + FieldValidatorBean fieldValidatorBean = Utils.convertSourceObjectToDestinationObject(contentResponseBean, FieldValidatorBean.class); + validator + .notNull(value, fieldId) + .minLength(value, fieldValidatorBean.getMinLength(), fieldId) // Only applies if minLength is not null + .maxLength(value, fieldValidatorBean.getMaxLength(), fieldId) // Only applies if maxLength is not null + .matchesPattern(value, fieldValidatorBean.getPattern(), fieldId); // Only applies if pattern is present + }); + + validator.validate(); + + } + + private Boolean getApplicationFormExist(ApplicationFormEntity applicationFormEntity) { + if(applicationFormEntity !=null) { + return true; + } + return false; + } } diff --git a/src/main/java/net/gepafin/tendermanagement/entities/ApplicationEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/ApplicationEntity.java new file mode 100644 index 00000000..8c9156e3 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/entities/ApplicationEntity.java @@ -0,0 +1,36 @@ +package net.gepafin.tendermanagement.entities; + +import jakarta.persistence.*; +import lombok.*; + +import java.time.LocalDateTime; + +@Entity +@Table(name = "APPLICATION") +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class ApplicationEntity extends BaseEntity { + + @ManyToOne + @JoinColumn(name = "USER_ID", nullable = false) + private UserEntity user; + + @Column(name = "SUBMISSION_DATE") + private LocalDateTime submissionDate; + + @Column(name = "STATUS", length = 255) + private String status; + + @Column(name = "COMMENTS", columnDefinition = "TEXT") + private String comments; + + @ManyToOne + @JoinColumn(name = "CALL_ID", nullable = false) + private CallEntity call; + + @Column(name="IS_DELETED") + private Boolean isDeleted; + + } \ No newline at end of file diff --git a/src/main/java/net/gepafin/tendermanagement/entities/ApplicationFormEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/ApplicationFormEntity.java new file mode 100644 index 00000000..a6cc56aa --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/entities/ApplicationFormEntity.java @@ -0,0 +1,20 @@ +package net.gepafin.tendermanagement.entities; + +import jakarta.persistence.*; +import lombok.*; + + +@Entity +@Table(name = "APPLICATION_FORM") +@Data +public class ApplicationFormEntity extends BaseEntity { + + @ManyToOne + @JoinColumn(name = "APPLICATION_ID", nullable = false) + private ApplicationEntity application; + + @ManyToOne + @JoinColumn(name = "FORM_ID", nullable = false) + private FormEntity form; + +} diff --git a/src/main/java/net/gepafin/tendermanagement/entities/ApplicationFormFieldEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/ApplicationFormFieldEntity.java new file mode 100644 index 00000000..fbab986d --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/entities/ApplicationFormFieldEntity.java @@ -0,0 +1,27 @@ +package net.gepafin.tendermanagement.entities; + +import jakarta.persistence.*; +import lombok.*; + +import java.time.LocalDateTime; + +@Entity +@Table(name = "APPLICATION_FORM_FIELD") +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class ApplicationFormFieldEntity extends BaseEntity { + + @ManyToOne + @JoinColumn(name = "APPLICATION_FORM_ID", nullable = false) + private ApplicationFormEntity applicationForm; + + @Column(name = "FIELD_ID") + private String fieldId; + + @Column(name = "FIELD_VALUE", length = 255) + private String fieldValue; + +} + diff --git a/src/main/java/net/gepafin/tendermanagement/enums/ApplicationStatusTypeEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/ApplicationStatusTypeEnum.java new file mode 100644 index 00000000..df120d29 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/enums/ApplicationStatusTypeEnum.java @@ -0,0 +1,22 @@ +package net.gepafin.tendermanagement.enums; + +import com.fasterxml.jackson.annotation.JsonValue; + +public enum ApplicationStatusTypeEnum { + + DRAFT("DRAFT"), + SUBMIT("SUBMIT"), + EXPIRED("EXPIRED"), + READY_TO_SUBMIT("READY_TO_SUBMIT"); + + private String value; + + ApplicationStatusTypeEnum(String value) { + this.value = value; + } + + @JsonValue + public String getValue() { + return value; + } +} diff --git a/src/main/java/net/gepafin/tendermanagement/enums/FormActionEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/FormActionEnum.java new file mode 100644 index 00000000..e5a64c59 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/enums/FormActionEnum.java @@ -0,0 +1,20 @@ +package net.gepafin.tendermanagement.enums; + +import com.fasterxml.jackson.annotation.JsonValue; + +public enum FormActionEnum { + + NEXT("NEXT"), + PREVIOUS("PREVIOUS"); + + private String value; + + FormActionEnum(String value) { + this.value = value; + } + + @JsonValue + public String getValue() { + return value; + } +} diff --git a/src/main/java/net/gepafin/tendermanagement/model/request/ApplicationFormFieldRequestBean.java b/src/main/java/net/gepafin/tendermanagement/model/request/ApplicationFormFieldRequestBean.java new file mode 100644 index 00000000..065c2f3f --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/model/request/ApplicationFormFieldRequestBean.java @@ -0,0 +1,16 @@ +package net.gepafin.tendermanagement.model.request; + +import jakarta.persistence.Column; +import lombok.Data; +import net.gepafin.tendermanagement.entities.ApplicationFormEntity; + +@Data +public class ApplicationFormFieldRequestBean { + + private Long id; + + private String fieldId; + + private String fieldValue; + +} diff --git a/src/main/java/net/gepafin/tendermanagement/model/request/ApplicationRequest.java b/src/main/java/net/gepafin/tendermanagement/model/request/ApplicationRequest.java new file mode 100644 index 00000000..920d1a2d --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/model/request/ApplicationRequest.java @@ -0,0 +1,16 @@ +package net.gepafin.tendermanagement.model.request; + +import lombok.Data; + +import java.time.LocalDateTime; + +@Data +public class ApplicationRequest { + + private LocalDateTime submissionDate; + + private String status; + + private String comments; + +} diff --git a/src/main/java/net/gepafin/tendermanagement/model/request/ApplicationRequestBean.java b/src/main/java/net/gepafin/tendermanagement/model/request/ApplicationRequestBean.java new file mode 100644 index 00000000..273519be --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/model/request/ApplicationRequestBean.java @@ -0,0 +1,13 @@ +package net.gepafin.tendermanagement.model.request; + +import jakarta.persistence.Column; +import lombok.Data; + +import java.time.LocalDateTime; +import java.util.List; + +@Data +public class ApplicationRequestBean { + + private List formFields; +} diff --git a/src/main/java/net/gepafin/tendermanagement/model/request/FieldValidatorBean.java b/src/main/java/net/gepafin/tendermanagement/model/request/FieldValidatorBean.java new file mode 100644 index 00000000..be94ffc0 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/model/request/FieldValidatorBean.java @@ -0,0 +1,18 @@ +package net.gepafin.tendermanagement.model.request; + +import lombok.Data; + +@Data +public class FieldValidatorBean { + + private Boolean isRequired; + + private Long minLength; + + private Long maxLength; + + private String pattern; + + private String custom; + +} \ No newline at end of file diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationFormFieldResponseBean.java b/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationFormFieldResponseBean.java new file mode 100644 index 00000000..f625d991 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationFormFieldResponseBean.java @@ -0,0 +1,16 @@ +package net.gepafin.tendermanagement.model.response; + +import lombok.Data; +import net.gepafin.tendermanagement.model.BaseBean; + +@Data +public class ApplicationFormFieldResponseBean extends BaseBean { + + private Long id; + + private Long applicationFormId; + + private String fieldId; + + private String fieldValue; +} diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationGetResponseBean.java b/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationGetResponseBean.java new file mode 100644 index 00000000..e566fc16 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationGetResponseBean.java @@ -0,0 +1,23 @@ +package net.gepafin.tendermanagement.model.response; + +import lombok.Data; +import net.gepafin.tendermanagement.model.response.ApplicationResponseBean; +import net.gepafin.tendermanagement.model.response.FormResponseBean; + +import java.time.LocalDateTime; +import java.util.List; + +@Data +public class ApplicationGetResponseBean { + + private Long id; + + private LocalDateTime submissionDate; + + private String status; + + private String comments; + + private List form; + +} diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationResponse.java b/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationResponse.java new file mode 100644 index 00000000..fdb0f6f3 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationResponse.java @@ -0,0 +1,22 @@ +package net.gepafin.tendermanagement.model.response; + +import lombok.Data; +import net.gepafin.tendermanagement.model.response.ApplicationFormFieldResponseBean; + +import java.time.LocalDateTime; +import java.util.List; + +@Data +public class ApplicationResponse{ + + private Long id; + + private Long callId; + + private LocalDateTime submissionDate; + + private String status; + + private String comments; + +} \ No newline at end of file diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationResponseBean.java b/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationResponseBean.java new file mode 100644 index 00000000..b9787067 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationResponseBean.java @@ -0,0 +1,25 @@ +package net.gepafin.tendermanagement.model.response; + +import lombok.Data; +import net.gepafin.tendermanagement.model.BaseBean; + +import java.time.LocalDateTime; +import java.util.List; + +@Data +public class ApplicationResponseBean extends BaseBean { + + private Long callId; + + private LocalDateTime submissionDate; + + private String status; + + private String comments; + + private List formFields; + + private Long currentFormId; + + private Long nextFormId; +} diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/FormApplicationResponse.java b/src/main/java/net/gepafin/tendermanagement/model/response/FormApplicationResponse.java new file mode 100644 index 00000000..3c7a322a --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/model/response/FormApplicationResponse.java @@ -0,0 +1,21 @@ +package net.gepafin.tendermanagement.model.response; + +import lombok.Data; +import net.gepafin.tendermanagement.model.response.ApplicationFormFieldResponseBean; +import net.gepafin.tendermanagement.model.response.ContentResponseBean; + +import java.util.List; + +@Data +public class FormApplicationResponse { + + private Long id; + + private String label; + + private Long callId; + + private List content; + + private List formFields; +} diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/NextOrPreviousFormResponse.java b/src/main/java/net/gepafin/tendermanagement/model/response/NextOrPreviousFormResponse.java new file mode 100644 index 00000000..1f7be289 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/model/response/NextOrPreviousFormResponse.java @@ -0,0 +1,12 @@ +package net.gepafin.tendermanagement.model.response; + +import lombok.Data; + +@Data +public class NextOrPreviousFormResponse { + + Long nextFormId; + + Long previousFormId; + +} \ No newline at end of file diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationFormFieldRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationFormFieldRepository.java new file mode 100644 index 00000000..89c70488 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationFormFieldRepository.java @@ -0,0 +1,27 @@ +package net.gepafin.tendermanagement.repositories; + +import net.gepafin.tendermanagement.entities.ApplicationFormFieldEntity; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import java.util.List; +import java.util.Optional; + +@Repository +public interface ApplicationFormFieldRepository extends JpaRepository { + + public List findByApplicationFormIdIn(List applicationFormIds); + + public List findByApplicationFormId(Long applicationFormId); + + public Optional findByFieldIdAndApplicationFormFormIdAndApplicationFormApplicationId( + String fieldId, Long formId, Long applicationId); + + public Optional findByFieldValueInAndApplicationFormFormIdInAndApplicationFormApplicationId( + List fieldValues, List previousFormIds, Long applicationId); + + public List findByFieldValueInAndApplicationFormApplicationId( + List fieldValue, Long applicationId); + +} diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationFormRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationFormRepository.java new file mode 100644 index 00000000..992eece3 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationFormRepository.java @@ -0,0 +1,20 @@ +package net.gepafin.tendermanagement.repositories; + +import net.gepafin.tendermanagement.entities.ApplicationFormEntity; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +public interface ApplicationFormRepository extends JpaRepository { + + public ApplicationFormEntity findByApplicationIdAndFormId(Long applicationId,Long formId); + + List findByApplicationIdIn(List applicationIds); + + public List findByApplicationId(Long applicationId); + + public List findByApplicationIdOrderByCreatedDateAsc(Long applicationId); + +} diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationRepository.java new file mode 100644 index 00000000..b32b8f46 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationRepository.java @@ -0,0 +1,22 @@ +package net.gepafin.tendermanagement.repositories; + +import net.gepafin.tendermanagement.entities.ApplicationEntity; +import net.gepafin.tendermanagement.entities.FaqEntity; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; +import org.springframework.stereotype.Repository; + +import java.util.List; +import java.util.Optional; + +@Repository +public interface ApplicationRepository extends JpaRepository { + + public Optional findByUserIdAndCallIdAndIsDeletedFalse(Long userId,Long callId); + + public List findByUserIdAndIsDeletedFalse(Long userId); + + @Query("SELECT a FROM ApplicationEntity a WHERE a.id = :id AND a.isDeleted = false") + Optional findById(@Param("id") Long id); +} diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/FlowDataRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/FlowDataRepository.java index 0f74d12b..8f752aa9 100644 --- a/src/main/java/net/gepafin/tendermanagement/repositories/FlowDataRepository.java +++ b/src/main/java/net/gepafin/tendermanagement/repositories/FlowDataRepository.java @@ -5,9 +5,16 @@ import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; import java.util.List; +import java.util.Optional; @Repository public interface FlowDataRepository extends JpaRepository { public List findByCallId(Long callId); + + public FlowDataEntity findByFormIdAndCallId(Long formId, Long callId); + + public Optional findByChoosenValueAndFormIdIn(String fieldValue, List nextFormIds); + + public List findByFormIdInAndCallId(List previousFormIds, Long callId); } diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/FlowEdgesRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/FlowEdgesRepository.java index ef4fbe91..3de65c17 100644 --- a/src/main/java/net/gepafin/tendermanagement/repositories/FlowEdgesRepository.java +++ b/src/main/java/net/gepafin/tendermanagement/repositories/FlowEdgesRepository.java @@ -10,4 +10,8 @@ import java.util.List; public interface FlowEdgesRepository extends JpaRepository { public List findByCallId(Long callId); + + public List findBySourceIdAndCallId(Long sourceId, Long callId); + + public List findByTargetIdAndCallId(Long targetId, Long callId); } diff --git a/src/main/java/net/gepafin/tendermanagement/service/ApplicationService.java b/src/main/java/net/gepafin/tendermanagement/service/ApplicationService.java new file mode 100644 index 00000000..013526ff --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/service/ApplicationService.java @@ -0,0 +1,33 @@ +package net.gepafin.tendermanagement.service; + +import jakarta.servlet.http.HttpServletRequest; +import net.gepafin.tendermanagement.entities.ApplicationEntity; +import net.gepafin.tendermanagement.model.request.ApplicationRequest; +import net.gepafin.tendermanagement.enums.ApplicationStatusTypeEnum; +import net.gepafin.tendermanagement.enums.FormActionEnum; +import net.gepafin.tendermanagement.model.request.ApplicationRequestBean; +import net.gepafin.tendermanagement.model.response.ApplicationGetResponseBean; +import net.gepafin.tendermanagement.model.response.ApplicationResponse; +import net.gepafin.tendermanagement.model.response.ApplicationResponseBean; +import net.gepafin.tendermanagement.model.response.NextOrPreviousFormResponse; + +import java.util.List; + +public interface ApplicationService { + + public ApplicationResponseBean createApplication(HttpServletRequest request, ApplicationRequestBean applicationRequestBean, Long formId); + + ApplicationGetResponseBean getApplicationByFormId(HttpServletRequest request, Long applicationId,Long formId); + + List getAllApplications(HttpServletRequest request); + + void deleteApplication(HttpServletRequest request, Long applicationId); + + public ApplicationEntity validateApplication(Long userId); + + public ApplicationResponse createApplication(HttpServletRequest request, ApplicationRequest applicationRequest, Long callId); + + public NextOrPreviousFormResponse getnextOrPreviousForm(HttpServletRequest request, Long applicationId, Long formId, FormActionEnum action); + + public void updateApplicationStatus(HttpServletRequest request, Long applicationId, ApplicationStatusTypeEnum status); +} diff --git a/src/main/java/net/gepafin/tendermanagement/service/FormService.java b/src/main/java/net/gepafin/tendermanagement/service/FormService.java index 7945c753..cf896b73 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/FormService.java +++ b/src/main/java/net/gepafin/tendermanagement/service/FormService.java @@ -1,7 +1,10 @@ package net.gepafin.tendermanagement.service; import jakarta.servlet.http.HttpServletRequest; +import net.gepafin.tendermanagement.entities.ApplicationEntity; import net.gepafin.tendermanagement.entities.FormEntity; +import net.gepafin.tendermanagement.entities.UserEntity; +import net.gepafin.tendermanagement.model.request.ApplicationFormFieldRequestBean; import net.gepafin.tendermanagement.model.request.FormRequest; import net.gepafin.tendermanagement.model.response.FormResponseBean; @@ -20,4 +23,6 @@ public interface FormService { public FormEntity validateForm(Long id); public List getFormsByCallId(HttpServletRequest request,Long callId); + + void validateFormField(List formFields, ApplicationEntity applicationEntity, FormEntity formEntity); } diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationServiceImpl.java new file mode 100644 index 00000000..c0e7b301 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationServiceImpl.java @@ -0,0 +1,92 @@ +package net.gepafin.tendermanagement.service.impl; + +import jakarta.servlet.http.HttpServletRequest; +import net.gepafin.tendermanagement.dao.ApplicationDao; +import net.gepafin.tendermanagement.dao.FlowFormDao; +import net.gepafin.tendermanagement.entities.ApplicationEntity; +import net.gepafin.tendermanagement.entities.FormEntity; +import net.gepafin.tendermanagement.entities.UserEntity; +import net.gepafin.tendermanagement.model.request.ApplicationRequest; +import net.gepafin.tendermanagement.enums.ApplicationStatusTypeEnum; +import net.gepafin.tendermanagement.enums.FormActionEnum; +import net.gepafin.tendermanagement.model.request.ApplicationRequestBean; +import net.gepafin.tendermanagement.model.response.ApplicationGetResponseBean; +import net.gepafin.tendermanagement.model.response.ApplicationResponse; +import net.gepafin.tendermanagement.model.response.ApplicationResponseBean; +import net.gepafin.tendermanagement.model.response.NextOrPreviousFormResponse; +import net.gepafin.tendermanagement.service.ApplicationService; +import net.gepafin.tendermanagement.service.FormService; +import net.gepafin.tendermanagement.util.Validator; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +@Service +public class ApplicationServiceImpl implements ApplicationService { + + @Autowired + private ApplicationDao applicationDao; + + @Autowired + private FlowFormDao flowFormDao; + + @Autowired + private FormService formService; + + @Autowired + private Validator validator; + + @Override + @Transactional(rollbackFor = Exception.class) + public ApplicationResponseBean createApplication(HttpServletRequest request, ApplicationRequestBean applicationRequestBean, Long formId) { + UserEntity userEntity = validator.validateUser(request); + return applicationDao.createApplication(applicationRequestBean,userEntity,formId); + } + + @Override + @Transactional(readOnly = true) + public ApplicationGetResponseBean getApplicationByFormId(HttpServletRequest request, Long applicationId,Long formId) { + UserEntity userEntity = validator.validateUser(request); + return applicationDao.getApplicationByFormId(applicationId,formId,userEntity); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void deleteApplication(HttpServletRequest request, Long applicationId) { + applicationDao.deleteById(applicationId); + } + + @Override + public ApplicationEntity validateApplication(Long id) { + return applicationDao.validateApplication(id); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public ApplicationResponse createApplication(HttpServletRequest request, ApplicationRequest applicationRequest, Long callId) { + UserEntity userEntity = validator.validateUser(request); + return applicationDao.createApplicationByCallId(applicationRequest,callId,userEntity); + } + + @Override + public NextOrPreviousFormResponse getnextOrPreviousForm(HttpServletRequest request, Long applicationId, Long formId, + FormActionEnum action) { + ApplicationEntity applicationEntity = validateApplication(applicationId); + return flowFormDao.getnextOrPreviousForm(applicationEntity, formId, action); + } + + @Override + public void updateApplicationStatus(HttpServletRequest request, Long applicationId, ApplicationStatusTypeEnum status) { + applicationDao.updateApplicationStatus(applicationId, status); + + } + + @Override + @Transactional(readOnly = true) + public List getAllApplications(HttpServletRequest request) { + UserEntity userEntity = validator.validateUser(request); + return applicationDao.getAllApplications(userEntity); + } +} diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/FormServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/FormServiceImpl.java index b8c9ab39..ee56bf88 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/FormServiceImpl.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/FormServiceImpl.java @@ -2,7 +2,10 @@ package net.gepafin.tendermanagement.service.impl; import jakarta.servlet.http.HttpServletRequest; import net.gepafin.tendermanagement.dao.FormDao; +import net.gepafin.tendermanagement.entities.ApplicationEntity; import net.gepafin.tendermanagement.entities.FormEntity; +import net.gepafin.tendermanagement.entities.UserEntity; +import net.gepafin.tendermanagement.model.request.ApplicationFormFieldRequestBean; import net.gepafin.tendermanagement.model.request.FormRequest; import net.gepafin.tendermanagement.model.response.FormResponseBean; import net.gepafin.tendermanagement.service.FormService; @@ -47,4 +50,10 @@ public class FormServiceImpl implements FormService { public List getFormsByCallId(HttpServletRequest request, Long callId) { return formDao.getFormsByCallId(callId); } + + @Override + public void validateFormField(List formFields, ApplicationEntity applicationEntity, FormEntity formEntity) { + formDao.validateFormField(formFields,applicationEntity, formEntity); + } + } diff --git a/src/main/java/net/gepafin/tendermanagement/util/FieldValidator.java b/src/main/java/net/gepafin/tendermanagement/util/FieldValidator.java index 7309dbd2..5e195945 100644 --- a/src/main/java/net/gepafin/tendermanagement/util/FieldValidator.java +++ b/src/main/java/net/gepafin/tendermanagement/util/FieldValidator.java @@ -37,6 +37,26 @@ public class FieldValidator { throw new ValidationException(Status.VALIDATION_ERROR, errors); } } + public FieldValidator minLength(String value, Long minLength, String fieldName) { + if (minLength != null && value != null && value.length() < minLength) { + errors.add(MessageFormat.format(Translator.toLocale(GepafinConstant.VALIDATION_FIELD_MIN_LENGTH), fieldName, minLength)); + } + return this; + } + + public FieldValidator maxLength(String value, Long maxLength, String fieldName) { + if (maxLength != null && value != null && value.length() > maxLength) { + errors.add(MessageFormat.format(Translator.toLocale(GepafinConstant.VALIDATION_FIELD_MAX_LENGTH), fieldName, maxLength)); + } + return this; + } + + public FieldValidator matchesPattern(String value, String pattern, String fieldName) { + if (value != null && pattern != null && !value.matches(pattern)) { + errors.add(MessageFormat.format(Translator.toLocale(GepafinConstant.VALIDATION_FIELD_PATTERN), fieldName)); + } + return this; + } public FieldValidator addError( String errorMessage) { errors.add(errorMessage); diff --git a/src/main/java/net/gepafin/tendermanagement/util/Utils.java b/src/main/java/net/gepafin/tendermanagement/util/Utils.java index c1819495..5560809f 100644 --- a/src/main/java/net/gepafin/tendermanagement/util/Utils.java +++ b/src/main/java/net/gepafin/tendermanagement/util/Utils.java @@ -5,12 +5,14 @@ import com.fasterxml.jackson.core.json.JsonReadFeature; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.type.TypeFactory; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import io.micrometer.common.util.StringUtils; import org.apache.commons.collections4.MapUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.lang.reflect.Type; import java.nio.charset.StandardCharsets; import java.util.Base64; import java.util.List; @@ -99,7 +101,13 @@ public class Utils { } public static List convertJsonStringToList(String jsonString, Class clazz) { try { - return mapper.readValue(jsonString, new TypeReference>() {}); + TypeReference> typeRef = new TypeReference>() { + @Override + public Type getType() { + return TypeFactory.defaultInstance().constructCollectionType(List.class, clazz); + } + }; + return mapper.readValue(jsonString, typeRef); } catch (Exception e) { e.printStackTrace(); // Handle the exception appropriately (e.g., throw a custom exception) @@ -129,5 +137,14 @@ public class Utils { } return null; } - + public static U convertSourceObjectToDestinationObject(T source, Class destinationClass) { + try { + mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); + mapper.registerModule(new JavaTimeModule()); + return mapper.convertValue(source, destinationClass); + } catch (Exception e) { + log.error("Error converting object: " + e.getMessage(), e); + } + return null; + } } diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/ApplicationApi.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/ApplicationApi.java new file mode 100644 index 00000000..85f6e345 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/ApplicationApi.java @@ -0,0 +1,132 @@ +package net.gepafin.tendermanagement.web.rest.api; + +import java.util.List; + +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.ExampleObject; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.validation.Valid; +import net.gepafin.tendermanagement.model.request.ApplicationRequest; +import net.gepafin.tendermanagement.enums.ApplicationStatusTypeEnum; +import net.gepafin.tendermanagement.enums.FormActionEnum; +import net.gepafin.tendermanagement.model.request.ApplicationRequestBean; +import net.gepafin.tendermanagement.model.response.ApplicationGetResponseBean; +import net.gepafin.tendermanagement.model.response.ApplicationResponse; +import net.gepafin.tendermanagement.model.response.ApplicationResponseBean; +import net.gepafin.tendermanagement.model.response.NextOrPreviousFormResponse; +import net.gepafin.tendermanagement.model.util.Response; +import net.gepafin.tendermanagement.web.rest.api.errors.ErrorConstants; + +@Validated +public interface ApplicationApi { + + @Operation(summary = "Api to create or update application", + responses = { + @ApiResponse(responseCode = "200", description = "OK"), + @ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.NOTFOUND_ERROR_EXAMPLE) })), + @ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.UNAUTHORIZED_ERROR_EXAMPLE) })), + @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) }) + @PutMapping(value = "/form/{formId}", + produces = { "application/json" }) + ResponseEntity> createApplication(HttpServletRequest request, + @Parameter(description = " Flow request object", required = true) @Valid @RequestBody ApplicationRequestBean applicationRequestBean, + @Parameter(description = "The form ID", required = true) @PathVariable("formId") Long formId); + + @Operation(summary = "Api to get an application by id", + responses = { + @ApiResponse(responseCode = "200", description = "OK"), + @ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.NOTFOUND_ERROR_EXAMPLE) })), + @ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.UNAUTHORIZED_ERROR_EXAMPLE) })), + @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) }) + @GetMapping(value = "/{applicationId}", produces = "application/json") + ResponseEntity> getApplicationByFormId(HttpServletRequest request, @Parameter(description = "The application id", required = true) @PathVariable(value = "applicationId", required = true) Long applicationId,@Parameter(description = "The form id", required = false) @RequestParam(value = "formId",required = false) Long formId); + + @Operation(summary = "Api to get all applications", + responses = { + @ApiResponse(responseCode = "200", description = "OK"), + @ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.NOTFOUND_ERROR_EXAMPLE) })), + @ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.UNAUTHORIZED_ERROR_EXAMPLE) })), + @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) }) + @GetMapping(value = "", produces = "application/json") + ResponseEntity>> getAllApplications(HttpServletRequest request); + + @Operation(summary = "Api to delete application", + responses = { + @ApiResponse(responseCode = "200", description = "OK"), + @ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.NOTFOUND_ERROR_EXAMPLE) })), + @ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.UNAUTHORIZED_ERROR_EXAMPLE) })), + @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) }) + @DeleteMapping(value = "/{applicationId}") + ResponseEntity> deleteApplication(HttpServletRequest request, + @Parameter(description = "The application id", required = true) @PathVariable("applicationId") Long applicationId); + + @Operation(summary = "Api to create application", + responses = { + @ApiResponse(responseCode = "200", description = "OK"), + @ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.NOTFOUND_ERROR_EXAMPLE) })), + @ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.UNAUTHORIZED_ERROR_EXAMPLE) })), + @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) }) + @PostMapping(value = "/call/{callId}", + produces = { "application/json" }) + ResponseEntity> createApplicationByCallId(HttpServletRequest request, + @Parameter(description = " Flow request object", required = true) @Valid @RequestBody ApplicationRequest applicationRequest, + @Parameter(description = "The call ID", required = true) @PathVariable("callId") Long callId); + + + + @Operation(summary = "Api to get an next or previous form by current form id", + responses = { + @ApiResponse(responseCode = "200", description = "OK"), + @ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.NOTFOUND_ERROR_EXAMPLE) })), + @ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.UNAUTHORIZED_ERROR_EXAMPLE) })), + @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) }) + @GetMapping(value = "/{applicationId}/form/next-previous", produces = "application/json") + ResponseEntity> getnextOrPreviousForm(HttpServletRequest request, + @Parameter(description = "The applicaltion id", required = true) @PathVariable("applicationId") Long applicationId, + @Parameter(description = "The form id", required = false) @RequestParam(value = "formId", required = false) Long formId, + @RequestParam("action") FormActionEnum action); + + + @Operation(summary = "Api to update application status", + responses = { + @ApiResponse(responseCode = "200", description = "OK"), + @ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.NOTFOUND_ERROR_EXAMPLE) })), + @ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.UNAUTHORIZED_ERROR_EXAMPLE) })), + @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) }) + @PutMapping(value = "/{applicationId}/status", produces = { "application/json" }) + ResponseEntity> updateApplicationStatus(HttpServletRequest request, + @Parameter(description = "The application id", required = true) @PathVariable("applicationId") Long applicationId, + @Parameter(description = "status", required = true)@RequestParam(value = "status", required = true) ApplicationStatusTypeEnum status); + + +} + diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/ApplicationApiController.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/ApplicationApiController.java new file mode 100644 index 00000000..9986412b --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/ApplicationApiController.java @@ -0,0 +1,92 @@ +package net.gepafin.tendermanagement.web.rest.api.impl; + +import jakarta.servlet.http.HttpServletRequest; +import net.gepafin.tendermanagement.config.Translator; +import net.gepafin.tendermanagement.constants.GepafinConstant; +import net.gepafin.tendermanagement.model.request.ApplicationRequest; +import net.gepafin.tendermanagement.enums.ApplicationStatusTypeEnum; +import net.gepafin.tendermanagement.enums.FormActionEnum; +import net.gepafin.tendermanagement.model.request.ApplicationRequestBean; +import net.gepafin.tendermanagement.model.response.ApplicationGetResponseBean; +import net.gepafin.tendermanagement.model.response.ApplicationResponse; +import net.gepafin.tendermanagement.model.response.ApplicationResponseBean; +import net.gepafin.tendermanagement.model.response.NextOrPreviousFormResponse; +import net.gepafin.tendermanagement.model.util.Response; +import net.gepafin.tendermanagement.service.ApplicationService; +import net.gepafin.tendermanagement.web.rest.api.ApplicationApi; +import net.gepafin.tendermanagement.web.rest.api.errors.Status; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import org.slf4j.Logger; + +import java.util.List; + + +@RestController +@RequestMapping("${openapi.gepafin.base-path:/v1/application}") +public class ApplicationApiController implements ApplicationApi { + + private final Logger log = LoggerFactory.getLogger(ApplicationApiController.class); + + @Autowired + private ApplicationService applicationService; + + @Override + public ResponseEntity> createApplication(HttpServletRequest request, ApplicationRequestBean applicationRequestBean, Long formId) { + ApplicationResponseBean applicationResponseBean= applicationService.createApplication(request,applicationRequestBean,formId); + return ResponseEntity.status(HttpStatus.CREATED) + .body(new Response<>(applicationResponseBean, Status.SUCCESS, Translator.toLocale(GepafinConstant.APPLICATION_CREATED_SUCCESS_MSG))); } + + @Override + public ResponseEntity> getApplicationByFormId(HttpServletRequest request + , Long applicationId,Long formId) { + log.info("Get Application by ID - Application ID: {}", applicationId); + ApplicationGetResponseBean application = applicationService.getApplicationByFormId(request,applicationId,formId); + return ResponseEntity.status(HttpStatus.OK) + .body(new Response<>(application, Status.SUCCESS, Translator.toLocale(GepafinConstant.GET_APPLICATION_SUCCESS_MSG))); + } + + @Override + public ResponseEntity> deleteApplication(HttpServletRequest request, + Long applicationId) { + log.info("Delete Application - Application ID: {}", applicationId); + applicationService.deleteApplication(request,applicationId); + return ResponseEntity.status(HttpStatus.OK) + .body(new Response<>(null, Status.SUCCESS, Translator.toLocale(GepafinConstant.DELETE_APPLICATION_SUCCESS_MSG))); + } + + @Override + public ResponseEntity> createApplicationByCallId(HttpServletRequest request, ApplicationRequest applicationRequest, Long callId) { + ApplicationResponse applicationResponseBean=applicationService.createApplication(request,applicationRequest,callId); + return ResponseEntity.status(HttpStatus.CREATED) + .body(new Response<>(applicationResponseBean, Status.SUCCESS, Translator.toLocale(GepafinConstant.APPLICATION_CREATED_SUCCESS_MSG))); + } + @Override + public ResponseEntity>> getAllApplications(HttpServletRequest request) { + List applications = applicationService.getAllApplications(request); + log.info("Get All Applications"); + return ResponseEntity.status(HttpStatus.OK) + .body(new Response<>(applications, Status.SUCCESS, Translator.toLocale(GepafinConstant.GET_APPLICATION_SUCCESS_MSG))); + } + + @Override + public ResponseEntity> getnextOrPreviousForm(HttpServletRequest request,Long applicationId, + Long formId, FormActionEnum action) { + NextOrPreviousFormResponse data = applicationService.getnextOrPreviousForm(request, applicationId, formId, action); + log.info("Get Next Or Previous Form "); + return ResponseEntity.status(HttpStatus.OK) + .body(new Response<>(data, Status.SUCCESS, Translator.toLocale(GepafinConstant.GET_APPLICATION_SUCCESS_MSG))); + } + + @Override + public ResponseEntity> updateApplicationStatus(HttpServletRequest request, Long applicationId, + ApplicationStatusTypeEnum status) { + applicationService.updateApplicationStatus(request, applicationId, status); + return ResponseEntity.status(HttpStatus.OK) + .body(new Response<>(null, Status.SUCCESS, Translator.toLocale(GepafinConstant.GET_APPLICATION_SUCCESS_MSG))); + } +} diff --git a/src/main/resources/db/changelog/db.changelog-1.0.0.xml b/src/main/resources/db/changelog/db.changelog-1.0.0.xml index 4554d996..fcba8de3 100644 --- a/src/main/resources/db/changelog/db.changelog-1.0.0.xml +++ b/src/main/resources/db/changelog/db.changelog-1.0.0.xml @@ -642,6 +642,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/message_en.properties b/src/main/resources/message_en.properties index 091922ff..50a234c8 100644 --- a/src/main/resources/message_en.properties +++ b/src/main/resources/message_en.properties @@ -139,4 +139,24 @@ flow.created.successfully=Flow created successfully. flow.fetched.successfully=Flow fetched successfully. flow.already.exists= Flow already exist for this call. flow.request.not.complete=Flow request is not complete. + +# Application related messages +application.created.success=Application successfully created. +application.updated.success=Application successfully updated. +application.deleted.success=Application successfully deleted. +application.get.success=Application details fetched successfully. +application.not.found=Application not found with the given ID. +application.form.field.not.found=Application form field not found. +Form.not.matches.to.call.initial.form=Form id does not matches to initial form id of call. +application.already.exists=Application already exists for this call. + +#Validation related messages +validation.field.required=Field {0} is required. +validation.field.min_length=Field {0} must be at least {1} characters long. +validation.field.max_length=Field {0} must be no more than {1} characters long. +validation.field.pattern=Field {0} does not match the required pattern. +validation.field.not_null=Field {0} must not be null. +validation.field.not_empty=Field {0} must not be empty. + +current.form.incomplete=Current form is not filled. flow.not.found=Flow not found. diff --git a/src/main/resources/message_it.properties b/src/main/resources/message_it.properties index fda677e8..e5c243df 100644 --- a/src/main/resources/message_it.properties +++ b/src/main/resources/message_it.properties @@ -135,4 +135,23 @@ flow.created.successfully=Flusso creato con successo. flow.fetched.successfully=Flusso recuperato con successo. flow.already.exists= Il flusso esiste gi� per questa chiamata. flow.request.not.complete=La richiesta di flusso non � completa. -flow.not.found=Flow not found. \ No newline at end of file + +# Application related messages +application.created.success=Applicazione creata con successo. +application.updated.success=Applicazione aggiornata con successo. +application.deleted.success=Applicazione eliminata con successo. +application.get.success=Dettagli dell'applicazione recuperati con successo. +application.not.found=Applicazione non trovata con l'ID fornito. +application.form.field.not.found=Campo del modulo di domanda non trovato. +Form.not.matches.to.call.initial.form=L'ID del modulo non corrisponde all'ID del modulo iniziale della chiamata. +application.already.exists=L'applicazione esiste gi� per questa chiamata. + +#Validation related messages +validation.field.required=Il campo {0} � obbligatorio. +validation.field.min_length=Il campo {0} deve essere lungo almeno {1} caratteri. +validation.field.max_length=Il campo {0} deve essere lungo al massimo {1} caratteri. +validation.field.pattern=Il campo {0} non corrisponde al modello richiesto. +validation.field.not_null=Il campo {0} non deve essere nullo. +validation.field.not_empty=Il campo {0} non deve essere vuoto. +current.form.incomplete=il modulo corrente non � compilato +flow.not.found=Flow not found.