diff --git a/src/main/java/net/gepafin/tendermanagement/dao/FormDao.java b/src/main/java/net/gepafin/tendermanagement/dao/FormDao.java index c315cfe6..9e85a843 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/FormDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/FormDao.java @@ -1,8 +1,10 @@ package net.gepafin.tendermanagement.dao; +import jakarta.servlet.http.HttpServletRequest; import net.gepafin.tendermanagement.config.Translator; import net.gepafin.tendermanagement.constants.GepafinConstant; import net.gepafin.tendermanagement.entities.*; +import net.gepafin.tendermanagement.enums.VersionActionTypeEnum; import net.gepafin.tendermanagement.model.request.*; import net.gepafin.tendermanagement.model.response.ContentResponseBean; import net.gepafin.tendermanagement.model.response.FormResponseBean; @@ -10,6 +12,7 @@ import net.gepafin.tendermanagement.repositories.*; import net.gepafin.tendermanagement.service.EvaluationCriteriaService; import net.gepafin.tendermanagement.util.DateTimeUtil; import net.gepafin.tendermanagement.util.FieldValidator; +import net.gepafin.tendermanagement.util.LoggingUtil; import net.gepafin.tendermanagement.util.Utils; import net.gepafin.tendermanagement.util.Validator; import net.gepafin.tendermanagement.web.rest.api.errors.CustomValidationException; @@ -62,19 +65,31 @@ public class FormDao { @Autowired private EvaluationCriteriaService evaluationCriteriaService; + @Autowired + private LoggingUtil loggingUtil; + + @Autowired + private HttpServletRequest request; + public FormEntity saveFormEntity(FormEntity formEntity){ formEntity=formRepository.save(formEntity); return formEntity; } - public FormEntity convertFormRequestToFormEntity(CallEntity callEntity, FormRequest formRequest){ - FormEntity formEntity=new FormEntity(); + public FormEntity convertFormRequestToFormEntity(CallEntity callEntity, FormRequest formRequest) { + + FormEntity formEntity = new FormEntity(); formEntity.setCall(callEntity); formEntity.setLabel(formRequest.getLabel()); formEntity.setContent(setContentResponseBean(formRequest.getContent())); - formEntity=saveFormEntity(formEntity); + formEntity = saveFormEntity(formEntity); + + /** This code is responsible for adding a version history log for the "Create form" operation. **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.INSERT).oldData(null).newData(formEntity).build()); + return formEntity; } + public FormResponseBean convertFormEntityToFormResponseBean(FormEntity formEntity) { FormResponseBean formResponseBean=new FormResponseBean(); formResponseBean.setId(formEntity.getId()); @@ -97,18 +112,35 @@ public class FormDao { return contentList; } - public FormResponseBean createForm(CallEntity callEntity,FormRequest formRequest){ + public FormResponseBean createForm(CallEntity callEntity, FormRequest formRequest) { + validateForm(formRequest); - List flowDataEntities=flowDataRepository.findByCallId(callEntity.getId()); - List flowEdgesEntities=flowEdgesRepository.findByCallId(callEntity.getId()); - if(Boolean.FALSE.equals(flowDataEntities.isEmpty() || flowDataEntities==null ) || Boolean.FALSE.equals(flowEdgesEntities.isEmpty() || flowEdgesEntities==null) ){ + //cloned entity for old call data. + CallEntity oldCallData = Utils.getClonedEntityForData(callEntity); + + List flowDataEntities = flowDataRepository.findByCallId(callEntity.getId()); + List flowEdgesEntities = flowEdgesRepository.findByCallId(callEntity.getId()); + if (Boolean.FALSE.equals(flowDataEntities.isEmpty() || flowDataEntities == null) || Boolean.FALSE.equals(flowEdgesEntities.isEmpty() || flowEdgesEntities == null)) { + + /** This code is responsible for adding a version history log for "delete all flow data" operation. **/ + flowDataEntities.stream().forEach(data -> loggingUtil.addVersionHistory( + VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.DELETE).oldData(data).newData(null).build())); + + /** This code is responsible for adding a version history log for "delete all flow edges" operation. **/ + flowEdgesEntities.stream().forEach(edge -> loggingUtil.addVersionHistory( + VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.DELETE).oldData(edge).newData(null).build())); + flowDataRepository.deleteAll(flowDataEntities); flowEdgesRepository.deleteAll(flowEdgesEntities); callEntity.setInitialForm(null); callEntity.setFinalForm(null); callRepository.save(callEntity); + + /** This code is responsible for adding a version history log for "update call" operation. **/ + loggingUtil.addVersionHistory( + VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldCallData).newData(callEntity).build()); } - FormEntity formEntity=convertFormRequestToFormEntity(callEntity, formRequest); + FormEntity formEntity = convertFormRequestToFormEntity(callEntity, formRequest); validateAndSaveCriteriaFormField(callEntity, formEntity, formRequest.getContent()); return convertFormEntityToFormResponseBean(formEntity); } @@ -134,10 +166,25 @@ public class FormDao { .filter(criteriaId -> !existingEvaluationCriteriaIds.contains(criteriaId)) .forEach(criteriaId -> createCriteriaFormField(callEntity, formEntity, content.getId(), criteriaId)); + // Prepare entities to be marked as deleted List toBeDeleted = existingCriteriaFields.stream() - .filter(criteriaFormField -> !criteriaList.contains(criteriaFormField.getEvaluationCriteriaId())) - .peek(data->data.setIsDeleted(Boolean.TRUE)) - .collect(Collectors.toList()); + .filter(criteriaFormField -> !criteriaList.contains(criteriaFormField.getEvaluationCriteriaId())) + .peek(data -> { + // Clone the entity before modification + CriteriaFormFieldEntity clonedData = Utils.getClonedEntityForData(data); + data.setIsDeleted(Boolean.TRUE); + + /** This code is responsible for adding a version history log for the "soft deleting criteria from field" operation. **/ + loggingUtil.addVersionHistory( + VersionHistoryRequest.builder() + .request(request) + .actionType(VersionActionTypeEnum.SOFT_DELETE) + .oldData(clonedData) + .newData(data) + .build() + ); + }) + .collect(Collectors.toList()); if (!toBeDeleted.isEmpty()) { criteriaFormFieldRepository.saveAll(toBeDeleted); @@ -146,6 +193,7 @@ public class FormDao { } + private void createCriteriaFormField(CallEntity callEntity, FormEntity formEntity, String formFieldId,Long evaluationCriteriaId) { EvaluationCriteriaEntity evaluationCriteria = evaluationCriteriaService.validateEvaluationCriteria(evaluationCriteriaId); @@ -160,6 +208,9 @@ public class FormDao { criteriaFormField.setIsDeleted(Boolean.FALSE); criteriaFormField.setEvaluationCriteriaId(evaluationCriteriaId); criteriaFormFieldRepository.save(criteriaFormField); + + /** This code is responsible for adding a version history log for the "creating criteria form field" operation. **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.INSERT).oldData(null).newData(criteriaFormField).build()); } @@ -168,74 +219,108 @@ public class FormDao { throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.REQUIRED_PARAMETER_NOT_FOUND_FOR_FORM)); } } - public FormResponseBean updateForm(UserEntity user, Long formId, FormRequest formRequest,Boolean forceDeleteFlow){ - ContentRequestBean contentRequestBean2=null; - String choosenField=null; + public FormResponseBean updateForm(UserEntity user, Long formId, FormRequest formRequest, Boolean forceDeleteFlow) { + + ContentRequestBean contentRequestBean2 = null; + String choosenField = null; FormEntity formEntity = validateForm(formId); + //cloned for old form data + FormEntity oldFormData = Utils.getClonedEntityForData(formEntity); + validator.validateUserWithCall(user, formEntity.getCall().getId()); -// callDao.validateUpdate(formEntity.getCall()); - List contentRequestBean = Utils.convertJsonStringToList(formEntity.getContent(), ContentRequestBean.class); - for (ContentRequestBean contentRequestBean1 : contentRequestBean) { - FlowDataEntity flowDataEntity = flowDataRepository.findByFormIdAndChoosenField(formEntity.getId(), contentRequestBean1.getId()); - if (flowDataEntity != null) { - choosenField = flowDataEntity.getChoosenField(); - if (Boolean.TRUE.equals(contentRequestBean1.getId().equals(choosenField))) { - contentRequestBean2 = contentRequestBean1; - break; - } + // callDao.validateUpdate(formEntity.getCall()); + List contentRequestBean = Utils.convertJsonStringToList(formEntity.getContent(), ContentRequestBean.class); + for (ContentRequestBean contentRequestBean1 : contentRequestBean) { + FlowDataEntity flowDataEntity = flowDataRepository.findByFormIdAndChoosenField(formEntity.getId(), contentRequestBean1.getId()); + if (flowDataEntity != null) { + choosenField = flowDataEntity.getChoosenField(); + if (Boolean.TRUE.equals(contentRequestBean1.getId().equals(choosenField))) { + contentRequestBean2 = contentRequestBean1; + break; } } - if (contentRequestBean2 != null) { - List settingRequestBeansDB = contentRequestBean2.getSettings(); - for (ContentRequestBean contentRequestBeanRequest : formRequest.getContent()) { - if (contentRequestBeanRequest.getId().equals(contentRequestBean2.getId())) { - for (SettingRequestBean settingRequestBeanRequest : contentRequestBeanRequest.getSettings()) { - for (SettingRequestBean settingRequestBeanDB : settingRequestBeansDB) { - if (settingRequestBeanRequest.getName().equals(settingRequestBeanDB.getName())) { - if (!settingRequestBeanRequest.getValue().equals(settingRequestBeanDB.getValue())) { - if (Boolean.TRUE.equals(forceDeleteFlow)) { - Utils.setIfUpdated(formEntity::getLabel, formEntity::setLabel, formRequest.getLabel()); - Utils.setIfUpdated(formEntity::getContent, formEntity::setContent, setContentResponseBean(formRequest.getContent())); - formEntity.setUpdatedDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); - formEntity = saveFormEntity(formEntity); - List flowDataEntities = flowDataRepository.findByCallId(formEntity.getCall().getId()); - List flowEdgesEntities = flowEdgesRepository.findByCallId(formEntity.getCall().getId()); - flowDataRepository.deleteAll(flowDataEntities); - flowEdgesRepository.deleteAll(flowEdgesEntities); - CallEntity callEntity = formEntity.getCall(); - callEntity.setInitialForm(null); - callEntity.setFinalForm(null); - callRepository.save(callEntity); - return convertFormEntityToFormResponseBean(formEntity); - } else { - throw new CustomValidationException( - Status.BAD_REQUEST, - Translator.toLocale(GepafinConstant.UPDATING_FORM_VALUE_IMPACT_ON_FLOW, choosenField) - ); - } - } - else { + } + if (contentRequestBean2 != null) { + List settingRequestBeansDB = contentRequestBean2.getSettings(); + for (ContentRequestBean contentRequestBeanRequest : formRequest.getContent()) { + if (contentRequestBeanRequest.getId().equals(contentRequestBean2.getId())) { + for (SettingRequestBean settingRequestBeanRequest : contentRequestBeanRequest.getSettings()) { + for (SettingRequestBean settingRequestBeanDB : settingRequestBeansDB) { + if (settingRequestBeanRequest.getName().equals(settingRequestBeanDB.getName())) { + if (!settingRequestBeanRequest.getValue().equals(settingRequestBeanDB.getValue())) { + if (Boolean.TRUE.equals(forceDeleteFlow)) { Utils.setIfUpdated(formEntity::getLabel, formEntity::setLabel, formRequest.getLabel()); Utils.setIfUpdated(formEntity::getContent, formEntity::setContent, setContentResponseBean(formRequest.getContent())); formEntity.setUpdatedDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); formEntity = saveFormEntity(formEntity); + + /** This code is responsible for adding a version history log for the "update from" operation. **/ + loggingUtil.addVersionHistory( + VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldFormData).newData(formEntity) + .build()); + + List flowDataEntities = flowDataRepository.findByCallId(formEntity.getCall().getId()); + List flowEdgesEntities = flowEdgesRepository.findByCallId(formEntity.getCall().getId()); + + /** This code is responsible for adding a version history log for "delete all flow data" operation. **/ + flowDataEntities.stream().forEach(data -> loggingUtil.addVersionHistory( + VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.DELETE).oldData(data).newData(null).build())); + + /** This code is responsible for adding a version history log for "delete all flow edges" operation. **/ + flowEdgesEntities.stream().forEach(edge -> loggingUtil.addVersionHistory( + VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.DELETE).oldData(edge).newData(null).build())); + + flowDataRepository.deleteAll(flowDataEntities); + flowEdgesRepository.deleteAll(flowEdgesEntities); + CallEntity callEntity = formEntity.getCall(); + //cloned for oldCall data + CallEntity oldCallData = Utils.getClonedEntityForData(callEntity); + + callEntity.setInitialForm(null); + callEntity.setFinalForm(null); + callRepository.save(callEntity); + + /** This code is responsible for adding a version history log for the "update call" operation. **/ + loggingUtil.addVersionHistory( + VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldCallData).newData(callEntity) + .build()); + return convertFormEntityToFormResponseBean(formEntity); + } else { + throw new CustomValidationException(Status.BAD_REQUEST, + Translator.toLocale(GepafinConstant.UPDATING_FORM_VALUE_IMPACT_ON_FLOW, choosenField)); } + } else { + Utils.setIfUpdated(formEntity::getLabel, formEntity::setLabel, formRequest.getLabel()); + Utils.setIfUpdated(formEntity::getContent, formEntity::setContent, setContentResponseBean(formRequest.getContent())); + formEntity.setUpdatedDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); + formEntity = saveFormEntity(formEntity); + + /** This code is responsible for adding a version history log for the "update from" operation. **/ + loggingUtil.addVersionHistory( + VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldFormData).newData(formEntity) + .build()); + + return convertFormEntityToFormResponseBean(formEntity); } } } } } } - else { + } else { Utils.setIfUpdated(formEntity::getLabel, formEntity::setLabel, formRequest.getLabel()); Utils.setIfUpdated(formEntity::getContent, formEntity::setContent, setContentResponseBean(formRequest.getContent())); formEntity.setUpdatedDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); formEntity = saveFormEntity(formEntity); + + /** This code is responsible for adding a version history log for the "Update form data" operation. **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldFormData).newData(formEntity).build()); + validateAndSaveCriteriaFormField(formEntity.getCall(), formEntity, formRequest.getContent()); return convertFormEntityToFormResponseBean(formEntity); } - return convertFormEntityToFormResponseBean(formEntity); + return convertFormEntityToFormResponseBean(formEntity); } public FormEntity validateForm(Long formId) { @@ -254,12 +339,28 @@ public class FormDao { validator.validateUserWithCall(user, formEntity.getCall().getId()); List flowDataEntities=flowDataRepository.findByCallId(formEntity.getCall().getId()); List flowEdgesEntities=flowEdgesRepository.findByCallId(formEntity.getCall().getId()); + + /** This code is responsible for adding a version history log for "delete all flow data" operation. **/ + flowDataEntities.stream().forEach(data -> loggingUtil.addVersionHistory( + VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.DELETE).oldData(data).newData(null).build())); + + /** This code is responsible for adding a version history log for "delete all flow edges" operation. **/ + flowEdgesEntities.stream().forEach(edge -> loggingUtil.addVersionHistory( + VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.DELETE).oldData(edge).newData(null).build())); + flowDataRepository.deleteAll(flowDataEntities); flowEdgesRepository.deleteAll(flowEdgesEntities); CallEntity callEntity=formEntity.getCall(); + //cloned for getting old call data + CallEntity oldCallData = Utils.getClonedEntityForData(callEntity); + callEntity.setFinalForm(null); callEntity.setInitialForm(null); callRepository.save(callEntity); + + /** This code is responsible for adding a version history log for the "Create Call" operation. **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.INSERT).oldData(null).newData(callEntity).build()); + formRepository.delete(formEntity); } public List getFormsByCallId(CallEntity callEntity){ diff --git a/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java index fefc12a9..0a92143b 100644 --- a/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java +++ b/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java @@ -141,7 +141,13 @@ public enum UserActionContextEnum { ADD_COMMENT_TO_AMENDMENT_REQUEST("ADD_COMMENT_TO_AMENDMENT_REQUEST"), UPDATE_COMMUNICATION_COMMENT("UPDATE_COMMUNICATION_COMMENT"), GET_AMENDMENT_COMMENT("GET_AMENDMENT_COMMENT"), - DELETE_COMMENT_FROM_AMENDMENT("DELETE_COMMENT_FROM_AMENDMENT"); + DELETE_COMMENT_FROM_AMENDMENT("DELETE_COMMENT_FROM_AMENDMENT"), + + /** form action context **/ + GET_FORM("GET_FORM"), + CREATE_FORM("CREATE_FORM"), + UPDATE_FORM("UPDATE_FORM"), + DELETE_FORM("DELETE_FORM"); private final String value; diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/FormApiController.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/FormApiController.java index 5b8b54a5..219ee509 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/FormApiController.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/FormApiController.java @@ -3,10 +3,14 @@ package net.gepafin.tendermanagement.web.rest.api.impl; import jakarta.servlet.http.HttpServletRequest; import net.gepafin.tendermanagement.config.Translator; import net.gepafin.tendermanagement.constants.GepafinConstant; +import net.gepafin.tendermanagement.enums.UserActionContextEnum; +import net.gepafin.tendermanagement.enums.UserActionLogsEnum; import net.gepafin.tendermanagement.model.request.FormRequest; +import net.gepafin.tendermanagement.model.request.UserActionRequest; import net.gepafin.tendermanagement.model.response.FormResponseBean; import net.gepafin.tendermanagement.model.util.Response; import net.gepafin.tendermanagement.service.FormService; +import net.gepafin.tendermanagement.util.LoggingUtil; import net.gepafin.tendermanagement.web.rest.api.FormApi; import net.gepafin.tendermanagement.web.rest.api.errors.Status; import org.springframework.beans.factory.annotation.Autowired; @@ -24,8 +28,15 @@ public class FormApiController implements FormApi { @Autowired private FormService formService; + @Autowired + private LoggingUtil loggingUtil; + @Override public ResponseEntity> createForm(HttpServletRequest request,Long callId, FormRequest formRequest) { + + /** This code is responsible for creating user action logs for the "Create form" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.INSERT).actionContext(UserActionContextEnum.CREATE_FORM).build()); + FormResponseBean formResponseBean = formService.createForm(request,callId, formRequest); return ResponseEntity.status(HttpStatus.CREATED) .body(new Response<>(formResponseBean, Status.SUCCESS, Translator.toLocale(GepafinConstant.FORM_CREATED_SUCCESSFULLY))); @@ -33,6 +44,10 @@ public class FormApiController implements FormApi { @Override public ResponseEntity> updateForm(HttpServletRequest request, Long formId, FormRequest formRequest,Boolean forceDeleteFlow) { + + /** This code is responsible for creating user action logs for the "Update form" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.UPDATE).actionContext(UserActionContextEnum.UPDATE_FORM).build()); + FormResponseBean formResponseBean = formService.updateForm(request, formId, formRequest,forceDeleteFlow); return ResponseEntity.status(HttpStatus.CREATED) .body(new Response<>(formResponseBean, Status.SUCCESS, Translator.toLocale(GepafinConstant.FORM_UPDATED_SUCCESSFULLY))); @@ -40,6 +55,10 @@ public class FormApiController implements FormApi { @Override public ResponseEntity> getFormById(HttpServletRequest request, Long formId) { + + /** This code is responsible for creating user action logs for the "Get form by id" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.VIEW).actionContext(UserActionContextEnum.GET_FORM).build()); + FormResponseBean formResponseBean=formService.getFormById(request,formId); return ResponseEntity.status(HttpStatus.OK) .body(new Response<>(formResponseBean, Status.SUCCESS, Translator.toLocale(GepafinConstant.FORM_FETCHED_SUCCESSFULLY))); @@ -47,6 +66,10 @@ public class FormApiController implements FormApi { @Override public ResponseEntity> deleteForm(HttpServletRequest request, Long formId) { + + /** This code is responsible for creating user action logs for the "delete form" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.DELETE).actionContext(UserActionContextEnum.DELETE_FORM).build()); + formService.deleteForm(request,formId); return ResponseEntity.status(HttpStatus.OK) .body(new Response<>(null, Status.SUCCESS, Translator.toLocale(GepafinConstant.FORM_DELETED_SUCCESSFULLY))); @@ -54,6 +77,10 @@ public class FormApiController implements FormApi { @Override public ResponseEntity>> getFormsByCallId(HttpServletRequest request, Long callId) { + + /** This code is responsible for creating user action logs for the "Get forms by call id" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.VIEW).actionContext(UserActionContextEnum.GET_FORM).build()); + List formResponseBean=formService.getFormsByCallId(request,callId); return ResponseEntity.status(HttpStatus.OK) .body(new Response<>(formResponseBean, Status.SUCCESS, Translator.toLocale(GepafinConstant.FORM_FETCHED_SUCCESSFULLY)));