From 6eafa7b33e87f0939f7ffe2e2c3bd70f81acabee Mon Sep 17 00:00:00 2001 From: piyushkag Date: Wed, 20 Nov 2024 12:03:09 +0530 Subject: [PATCH 01/43] Added logging mechanism for user actions. --- .../config/CachedBodyFilter.java | 26 +++ .../config/CachedBodyHttpServletRequest.java | 76 +++++++++ .../config/RequestCachingFilter.java | 25 +++ .../config/UniqueSessionInterceptor.java | 29 ++++ .../config/jwt/TokenProvider.java | 47 ++++-- .../constants/GepafinConstant.java | 6 + .../gepafin/tendermanagement/dao/CallDao.java | 32 +++- .../gepafin/tendermanagement/dao/FaqDao.java | 27 +++- .../tendermanagement/dao/LookUpDataDao.java | 43 +++-- .../gepafin/tendermanagement/dao/UserDao.java | 5 +- .../entities/UserActionEntity.java | 43 +++++ .../entities/VersionHistoryEntity.java | 33 ++++ .../enums/UserActionContextEnum.java | 20 +++ .../enums/UserActionLogsEnum.java | 20 +++ .../enums/VersionActionTypeEnum.java | 20 +++ .../model/request/UserActionRequest.java | 12 ++ .../model/request/VersionHistoryRequest.java | 17 ++ .../model/util/LogResponse.java | 28 ++++ .../repositories/UserActionsRepository.java | 9 ++ .../VersionHistoryRepository.java | 9 ++ .../service/impl/AuthenticationService.java | 10 +- .../tendermanagement/util/IpAddressUtils.java | 45 ++++++ .../tendermanagement/util/LoggingUtil.java | 149 ++++++++++++++++++ .../gepafin/tendermanagement/util/Utils.java | 41 ++++- .../web/rest/api/impl/CallApiController.java | 21 ++- .../db/changelog/db.changelog-1.0.0.xml | 47 ++++++ 26 files changed, 798 insertions(+), 42 deletions(-) create mode 100644 src/main/java/net/gepafin/tendermanagement/config/CachedBodyFilter.java create mode 100644 src/main/java/net/gepafin/tendermanagement/config/CachedBodyHttpServletRequest.java create mode 100644 src/main/java/net/gepafin/tendermanagement/config/RequestCachingFilter.java create mode 100644 src/main/java/net/gepafin/tendermanagement/config/UniqueSessionInterceptor.java create mode 100644 src/main/java/net/gepafin/tendermanagement/entities/UserActionEntity.java create mode 100644 src/main/java/net/gepafin/tendermanagement/entities/VersionHistoryEntity.java create mode 100644 src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java create mode 100644 src/main/java/net/gepafin/tendermanagement/enums/UserActionLogsEnum.java create mode 100644 src/main/java/net/gepafin/tendermanagement/enums/VersionActionTypeEnum.java create mode 100644 src/main/java/net/gepafin/tendermanagement/model/request/UserActionRequest.java create mode 100644 src/main/java/net/gepafin/tendermanagement/model/request/VersionHistoryRequest.java create mode 100644 src/main/java/net/gepafin/tendermanagement/model/util/LogResponse.java create mode 100644 src/main/java/net/gepafin/tendermanagement/repositories/UserActionsRepository.java create mode 100644 src/main/java/net/gepafin/tendermanagement/repositories/VersionHistoryRepository.java create mode 100644 src/main/java/net/gepafin/tendermanagement/util/IpAddressUtils.java create mode 100644 src/main/java/net/gepafin/tendermanagement/util/LoggingUtil.java diff --git a/src/main/java/net/gepafin/tendermanagement/config/CachedBodyFilter.java b/src/main/java/net/gepafin/tendermanagement/config/CachedBodyFilter.java new file mode 100644 index 00000000..c164dc60 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/config/CachedBodyFilter.java @@ -0,0 +1,26 @@ +package net.gepafin.tendermanagement.config; + +import jakarta.servlet.Filter; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import org.springframework.stereotype.Component; + +import java.io.IOException; + +@Component +public class CachedBodyFilter implements Filter { + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { + + if (request instanceof HttpServletRequest httpServletRequest) { + CachedBodyHttpServletRequest cachedRequest = new CachedBodyHttpServletRequest(httpServletRequest); + chain.doFilter(cachedRequest, response); + } else { + chain.doFilter(request, response); + } + } +} diff --git a/src/main/java/net/gepafin/tendermanagement/config/CachedBodyHttpServletRequest.java b/src/main/java/net/gepafin/tendermanagement/config/CachedBodyHttpServletRequest.java new file mode 100644 index 00000000..f5c1582b --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/config/CachedBodyHttpServletRequest.java @@ -0,0 +1,76 @@ +package net.gepafin.tendermanagement.config; + +import jakarta.servlet.ReadListener; +import jakarta.servlet.ServletInputStream; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequestWrapper; + +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; + +public class CachedBodyHttpServletRequest extends HttpServletRequestWrapper { + + private final byte[] cachedBody; + + public CachedBodyHttpServletRequest(HttpServletRequest request) throws IOException { + + super(request); + InputStream requestInputStream = request.getInputStream(); + this.cachedBody = requestInputStream.readAllBytes(); + } + + @Override + public ServletInputStream getInputStream() { + + ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(cachedBody); + return new ServletInputStreamWrapper(byteArrayInputStream); + } + + @Override + public BufferedReader getReader() throws IOException { + + ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(cachedBody); + return new BufferedReader(new InputStreamReader(byteArrayInputStream)); + } + + public String getCachedBodyAsString() { + + return new String(cachedBody); + } + + private static class ServletInputStreamWrapper extends ServletInputStream { + + private final ByteArrayInputStream byteArrayInputStream; + + public ServletInputStreamWrapper(ByteArrayInputStream byteArrayInputStream) { + + this.byteArrayInputStream = byteArrayInputStream; + } + + @Override + public int read() throws IOException { + + return byteArrayInputStream.read(); + } + + @Override + public boolean isFinished() { + + return byteArrayInputStream.available() == 0; + } + + @Override + public boolean isReady() { + + return true; + } + + @Override + public void setReadListener(ReadListener readListener) { + + } + } +} diff --git a/src/main/java/net/gepafin/tendermanagement/config/RequestCachingFilter.java b/src/main/java/net/gepafin/tendermanagement/config/RequestCachingFilter.java new file mode 100644 index 00000000..1ce8c840 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/config/RequestCachingFilter.java @@ -0,0 +1,25 @@ +package net.gepafin.tendermanagement.config; + +import jakarta.servlet.Filter; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import org.springframework.stereotype.Component; + +import java.io.IOException; + +@Component +public class RequestCachingFilter implements Filter { + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { + if (request instanceof HttpServletRequest) { + HttpServletRequest cachedRequest = new CachedBodyHttpServletRequest((HttpServletRequest) request); + chain.doFilter(cachedRequest, response); + } else { + chain.doFilter(request, response); + } + } +} diff --git a/src/main/java/net/gepafin/tendermanagement/config/UniqueSessionInterceptor.java b/src/main/java/net/gepafin/tendermanagement/config/UniqueSessionInterceptor.java new file mode 100644 index 00000000..9f438d91 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/config/UniqueSessionInterceptor.java @@ -0,0 +1,29 @@ +package net.gepafin.tendermanagement.config; + +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpSession; +import org.springframework.stereotype.Component; +import org.springframework.web.servlet.HandlerInterceptor; + +@Component +public class UniqueSessionInterceptor implements HandlerInterceptor { + + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { + + request.getSession(true); + return true; + } + + @Override + public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { + + if ("/v1/user/logout".equals(request.getRequestURI())) { + HttpSession session = request.getSession(false); + if (session != null) { + session.invalidate(); + } + } + } +} \ No newline at end of file diff --git a/src/main/java/net/gepafin/tendermanagement/config/jwt/TokenProvider.java b/src/main/java/net/gepafin/tendermanagement/config/jwt/TokenProvider.java index 884c848f..41d9fc16 100644 --- a/src/main/java/net/gepafin/tendermanagement/config/jwt/TokenProvider.java +++ b/src/main/java/net/gepafin/tendermanagement/config/jwt/TokenProvider.java @@ -6,6 +6,7 @@ import io.jsonwebtoken.SignatureAlgorithm; import io.jsonwebtoken.security.Keys; import jakarta.annotation.PostConstruct; import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import net.gepafin.tendermanagement.config.Translator; import net.gepafin.tendermanagement.constants.GepafinConstant; import net.gepafin.tendermanagement.entities.UserEntity; @@ -15,6 +16,7 @@ import net.gepafin.tendermanagement.web.rest.api.errors.Status; import net.gepafin.tendermanagement.web.rest.api.errors.UnauthorizedAccessException; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.time.DateUtils; +import org.apache.http.HttpResponse; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -23,6 +25,7 @@ import org.springframework.security.authentication.UsernamePasswordAuthenticatio import org.springframework.security.core.Authentication; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.stereotype.Component; @@ -49,9 +52,11 @@ public class TokenProvider { @Autowired private UserRepository userRepository; + @Autowired + HttpServletResponse response; + private SecretKey key; - private static final String AUTHORITIES_KEY = "auth"; private static final String MERCHANTID="merchantId"; static final String AUTH_SECRET = "X-Api-Secret"; @@ -82,11 +87,11 @@ public class TokenProvider { log.info("JWT Secret Key initialized."); } - public String createToken(Boolean rememberMe, UserEntity user) { -// String authorities = authentication.getAuthorities().stream() -// .map(GrantedAuthority::getAuthority) -// .collect(Collectors.joining(",")); - String authorities = user.getRoleEntity().getRoleType(); + public String createToken(Boolean rememberMe, UserEntity user, Long loginAttemptId) { + // String authorities = authentication.getAuthorities().stream() + // .map(GrantedAuthority::getAuthority) + // .collect(Collectors.joining(",")); + String authorities = user.getRoleEntity().getRoleType(); Long now; Date validity; @@ -103,19 +108,19 @@ public class TokenProvider { String payload = user.getEmail(); if(user != null) { payload += ":"+user.getId(); - } - - if(user != null) { payload += ":"+user.getHub().getId(); } String token = Jwts.builder() .setSubject(payload) - .claim("auth", authorities) + .claim(GepafinConstant.LOGIN_ATTEMPT_ID, loginAttemptId) + .claim(GepafinConstant.USER_ID, user.getId() != null ? user.getId() : null) + .claim(GepafinConstant.AUTH, authorities) .signWith(key, SignatureAlgorithm.HS512) .setExpiration(validity) .compact(); + response.setHeader("Authorization", "Bearer " + token); log.debug("Generated token: {}", token); return token; } @@ -249,4 +254,26 @@ public class TokenProvider { return null; // Return null if token is not found or not in Bearer format } + public Claims getClaimsFromToken(String token) { + + return Jwts.parser().setSigningKey(key).parseClaimsJws(token).getBody(); + } + + public String getCurrentActiveUserEmail() { + + var authentication = SecurityContextHolder.getContext().getAuthentication(); + if (authentication != null && authentication.isAuthenticated()) { + UserDetails userDetails = (UserDetails) authentication.getPrincipal(); + String email = userDetails.getUsername(); + int lastColonIndex = email.lastIndexOf(":"); + int secondLastColonIndex = email.lastIndexOf(":", lastColonIndex - 1); + + if (secondLastColonIndex != -1) { + return email.substring(0, secondLastColonIndex); + } else { + return email; + } + } + return null; + } } \ No newline at end of file diff --git a/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java b/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java index b1704c6a..d1f65647 100644 --- a/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java +++ b/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java @@ -292,5 +292,11 @@ public class GepafinConstant { public static final String ENCRYPT_KEY = "U2VjdXJlRW5jcnlwdEtleQ=="; public static final String APPLICATION_DOCUMENTS_NOT_FOUND_MSG = "application.documents.not.found"; public static final String DUPLICATE_BENEFICIARY_CALL = "beneficiary.call.duplicate"; + public static final String AUTH = "auth"; + + //Logging + public static final String USER_ID = "userId"; + public static final String LOGIN_ATTEMPT_ID = "loginAttemptId"; + public static final String USER_ACTION_ID = "userActionId"; } diff --git a/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java b/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java index fe692b69..6aa766e1 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java @@ -15,10 +15,13 @@ import java.util.zip.ZipOutputStream; import jakarta.servlet.http.HttpServletRequest; import net.gepafin.tendermanagement.entities.*; import net.gepafin.tendermanagement.enums.DocumentSourceTypeEnum; +import net.gepafin.tendermanagement.enums.VersionActionTypeEnum; +import net.gepafin.tendermanagement.model.request.VersionHistoryRequest; import net.gepafin.tendermanagement.model.response.*; import net.gepafin.tendermanagement.repositories.*; import net.gepafin.tendermanagement.service.*; import net.gepafin.tendermanagement.util.DateTimeUtil; +import net.gepafin.tendermanagement.util.LoggingUtil; import net.gepafin.tendermanagement.util.Utils; import net.gepafin.tendermanagement.util.Validator; import org.h2.util.IOUtils; @@ -95,6 +98,11 @@ public class CallDao { @Autowired private Validator validator; + @Autowired + private LoggingUtil loggingUtil; + + @Autowired + private HttpServletRequest request; public CallResponse createCallStep1(CreateCallRequestStep1 createCallRequest, UserEntity userEntity) { createCallRequest.setRegionId(userEntity.getRoleEntity().getRegion().getId()); @@ -144,7 +152,8 @@ public class CallDao { public CallEntity convertToCallEntity(CreateCallRequestStep1 createCallRequest, UserEntity userEntity) { CallEntity callEntity = new CallEntity(); -// validateCallEntity(createCallRequest); + VersionHistoryRequest versionHistoryRequest = new VersionHistoryRequest(); + // validateCallEntity(createCallRequest); RegionEntity region = regionRepository.findById(createCallRequest.getRegionId()) .orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.REGION_NOT_FOUND))); @@ -180,6 +189,11 @@ public class CallDao { callEntity.setEndTime(DateTimeUtil.parseTime(createCallRequest.getEndTime())); callEntity.setHub(userEntity.getHub()); callEntity = callRepository.save(callEntity); + versionHistoryRequest.setOldData(null); + versionHistoryRequest.setNewData(callEntity); + versionHistoryRequest.setRequest(request); + versionHistoryRequest.setActionType(VersionActionTypeEnum.INSERT); + loggingUtil.addVersionHistory(versionHistoryRequest); return callEntity; } @@ -197,7 +211,15 @@ public class CallDao { List evaluationCriteriaEntities = criteriaReqList.stream() .map(req -> convertToEvaluationCriteriaEntity(req, callEntity, type)).collect(Collectors.toList()); - evaluationCriteriaRepository.saveAll(evaluationCriteriaEntities); + List data = evaluationCriteriaRepository.saveAll(evaluationCriteriaEntities); + data.forEach(entity -> { + VersionHistoryRequest versionHistoryRequest = new VersionHistoryRequest(); + versionHistoryRequest.setOldData(null); + versionHistoryRequest.setNewData(entity); + versionHistoryRequest.setRequest(request); + versionHistoryRequest.setActionType(VersionActionTypeEnum.INSERT); + loggingUtil.addVersionHistory(versionHistoryRequest); + }); return evaluationCriteriaEntities; } @@ -394,6 +416,7 @@ public class CallDao { private List createCallTargetAudienceCheckList(CallEntity callEntity, List lookUpDataEntities) { List lookUpDataResponses = new ArrayList<>(); + VersionHistoryRequest versionHistoryRequest = new VersionHistoryRequest(); for (LookUpDataEntity lookUpDataEntity : lookUpDataEntities) { CallTargetAudienceChecklistEntity callTargetAudienceChecklistEntity = new CallTargetAudienceChecklistEntity(); callTargetAudienceChecklistEntity.setIsValidated(false); @@ -402,6 +425,11 @@ public class CallDao { callTargetAudienceChecklistEntity.setIsDeleted(false); callTargetAudienceChecklistEntity = callTargetAudienceChecklistRepository .save(callTargetAudienceChecklistEntity); + versionHistoryRequest.setOldData(null); + versionHistoryRequest.setNewData(callTargetAudienceChecklistEntity); + versionHistoryRequest.setActionType(VersionActionTypeEnum.INSERT); + versionHistoryRequest.setRequest(request); + loggingUtil.addVersionHistory(versionHistoryRequest); lookUpDataResponses.add(convertToLookUpDataResponseBean(callTargetAudienceChecklistEntity)); } return lookUpDataResponses; diff --git a/src/main/java/net/gepafin/tendermanagement/dao/FaqDao.java b/src/main/java/net/gepafin/tendermanagement/dao/FaqDao.java index cfec2fe2..fb6050da 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/FaqDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/FaqDao.java @@ -1,20 +1,24 @@ 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.CallEntity; import net.gepafin.tendermanagement.entities.FaqEntity; -import net.gepafin.tendermanagement.entities.LookUpDataEntity; import net.gepafin.tendermanagement.entities.UserEntity; import net.gepafin.tendermanagement.enums.RoleStatusEnum; import net.gepafin.tendermanagement.entities.LookUpDataEntity.LookUpDataTypeEnum; +import net.gepafin.tendermanagement.enums.VersionActionTypeEnum; import net.gepafin.tendermanagement.model.request.FaqReq; +import net.gepafin.tendermanagement.model.request.VersionHistoryRequest; import net.gepafin.tendermanagement.model.response.FaqResponseBean; import net.gepafin.tendermanagement.repositories.FaqRepository; import net.gepafin.tendermanagement.service.CallService; import net.gepafin.tendermanagement.service.CompanyService; import net.gepafin.tendermanagement.service.LookUpDataService; import net.gepafin.tendermanagement.util.DateTimeUtil; +import net.gepafin.tendermanagement.util.LoggingUtil; +import net.gepafin.tendermanagement.util.Utils; import net.gepafin.tendermanagement.util.Validator; import net.gepafin.tendermanagement.web.rest.api.errors.CustomValidationException; import net.gepafin.tendermanagement.web.rest.api.errors.ResourceNotFoundException; @@ -45,10 +49,16 @@ public class FaqDao { @Autowired private CompanyService companyService; + @Autowired + HttpServletRequest request; + + @Autowired + LoggingUtil loggingUtil; + public FaqResponseBean createFaq(FaqReq faqRequest, UserEntity userEntity, Long callId, Long companyId) { CallEntity callEntity = callService.validateCall(callId); FaqEntity entity = createOrUpdateFaqEntity(faqRequest, callEntity, userEntity, - LookUpDataEntity.LookUpDataTypeEnum.FAQ); + LookUpDataTypeEnum.FAQ); if (validator.checkIsBeneficiary() && companyId == null) { throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.COMPANY_ID_MANDATORY)); @@ -68,7 +78,7 @@ public class FaqDao { public FaqResponseBean updateFaq(Long id, FaqReq faqRequest, UserEntity userEntity) { FaqEntity entity = validateFaq(id); faqRequest.setId(entity.getId()); - createOrUpdateFaqEntity(faqRequest, entity.getCall(), userEntity, LookUpDataEntity.LookUpDataTypeEnum.FAQ); + createOrUpdateFaqEntity(faqRequest, entity.getCall(), userEntity, LookUpDataTypeEnum.FAQ); return convertToFaqResponseBean(entity); } @@ -93,10 +103,13 @@ public class FaqDao { public FaqEntity createOrUpdateFaqEntity(FaqReq faqReq, CallEntity callEntity, UserEntity userEntity, LookUpDataTypeEnum type) { FaqEntity faqEntity = null; + FaqEntity oldFaqData = null; + VersionHistoryRequest versionHistoryRequest = new VersionHistoryRequest(); if (isExistingFaq(faqReq)) { faqEntity = faqRepository.findByIdAndCallIdAndIsDeletedFalse(faqReq.getId(), callEntity.getId()) .orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.FAQ_NOT_FOUND))); + oldFaqData = Utils.getClonedEntityForData(faqEntity); } else { if (Boolean.FALSE.equals(userEntity.getRoleEntity().getRoleType().equals(RoleStatusEnum.ROLE_BENEFICIARY.getValue()))) { lookUpDataService.getOrCreateLookUpDataEntity(faqReq, type); @@ -115,7 +128,13 @@ public class FaqDao { setIfUpdated(faqEntity::getValue, faqEntity::setValue, faqReq.getValue()); setIfUpdated(faqEntity::getResponse, faqEntity::setResponse, faqReq.getResponse()); setIfUpdated(faqEntity::getIsVisible, faqEntity::setIsVisible, faqReq.getIsVisible()); - return faqRepository.save(faqEntity); + FaqEntity newFaqData = faqRepository.save(faqEntity); + versionHistoryRequest.setOldData(oldFaqData); + versionHistoryRequest.setNewData(newFaqData); + versionHistoryRequest.setActionType(VersionActionTypeEnum.INSERT); + versionHistoryRequest.setRequest(request); + loggingUtil.addVersionHistory(versionHistoryRequest); + return newFaqData; } private boolean isExistingFaq(FaqReq faqReq) { diff --git a/src/main/java/net/gepafin/tendermanagement/dao/LookUpDataDao.java b/src/main/java/net/gepafin/tendermanagement/dao/LookUpDataDao.java index 1a31c306..f9a7f4e2 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/LookUpDataDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/LookUpDataDao.java @@ -1,11 +1,17 @@ package net.gepafin.tendermanagement.dao; +import jakarta.servlet.http.HttpServletRequest; import net.gepafin.tendermanagement.entities.LookUpDataEntity; import net.gepafin.tendermanagement.entities.LookUpDataEntity.LookUpDataTypeEnum; +import net.gepafin.tendermanagement.enums.UserActionLogsEnum; +import net.gepafin.tendermanagement.enums.VersionActionTypeEnum; import net.gepafin.tendermanagement.model.request.LookUpDataReq; import net.gepafin.tendermanagement.model.request.LookUpDataRequest; +import net.gepafin.tendermanagement.model.request.VersionHistoryRequest; import net.gepafin.tendermanagement.model.response.LookUpDataResponseBean; import net.gepafin.tendermanagement.repositories.LookUpDataRepository; +import net.gepafin.tendermanagement.util.LoggingUtil; +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; @@ -25,6 +31,12 @@ public class LookUpDataDao { @Autowired private LookUpDataRepository lookUpDataRepository; + @Autowired + HttpServletRequest request; + + @Autowired + LoggingUtil loggingUtil; + public LookUpDataResponseBean createLookUpData(LookUpDataRequest lookUpDataReq) { LookUpDataEntity entity = convertLookUpDataReqToLookUpDataEntity(lookUpDataReq); return convertLookUpDataEntityToResponseBean(entity); @@ -87,18 +99,25 @@ public class LookUpDataDao { .map(this::convertLookUpDataEntityToResponseBean) .collect(Collectors.toList()); } - - public LookUpDataEntity getOrCreateLookUpDataEntity(LookUpDataReq req, - LookUpDataEntity.LookUpDataTypeEnum type) { - if (req.getLookUpDataId() == null || req.getLookUpDataId().equals(0l)) { - LookUpDataEntity newEntity = new LookUpDataEntity(); - newEntity.setTitle(req.getTitle()); - newEntity.setValue(req.getValue()); - newEntity.setResponse(req.getResponse()); - newEntity.setType(type.getValue()); - validateLookUpDataEntity(newEntity); - return lookUpDataRepository.save(newEntity); - } + + public LookUpDataEntity getOrCreateLookUpDataEntity(LookUpDataReq req, LookUpDataEntity.LookUpDataTypeEnum type) { + + if (req.getLookUpDataId() == null || req.getLookUpDataId().equals(0L)) { + LookUpDataEntity newEntity = new LookUpDataEntity(); + VersionHistoryRequest versionHistoryRequest = new VersionHistoryRequest(); + newEntity.setTitle(req.getTitle()); + newEntity.setValue(req.getValue()); + newEntity.setResponse(req.getResponse()); + newEntity.setType(type.getValue()); + validateLookUpDataEntity(newEntity); + LookUpDataEntity lookUpDataEntity = lookUpDataRepository.save(newEntity); + versionHistoryRequest.setOldData(null); + versionHistoryRequest.setNewData(lookUpDataEntity); + versionHistoryRequest.setActionType(VersionActionTypeEnum.INSERT); + versionHistoryRequest.setRequest(request); + loggingUtil.addVersionHistory(versionHistoryRequest); + return lookUpDataEntity; + } return lookUpDataRepository.findById(req.getLookUpDataId()) .orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND, diff --git a/src/main/java/net/gepafin/tendermanagement/dao/UserDao.java b/src/main/java/net/gepafin/tendermanagement/dao/UserDao.java index 53d21fc5..d5cda645 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/UserDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/UserDao.java @@ -94,13 +94,14 @@ public class UserDao { log.info("User created with ID: {}", userEntity.getId()); LoginReq loginReq=new LoginReq(); loginReq.setEmail(userEntity.getEmail()); + LoginAttemptEntity loginAttemptEntity = null; if(userEntity!=null){ - LoginAttemptEntity loginAttemptEntity =authenticationService.prepareLoginAttemptEntity(loginReq, request); + loginAttemptEntity = authenticationService.prepareLoginAttemptEntity(loginReq, request); log.info("Authentication failed for email: {}", loginReq.getEmail()); loginAttemptEntity.setUserId(userEntity.getId()); authenticationService.createSuccessLoginAttempt(loginAttemptEntity); } - return authService.getJWTTokenBean(userEntity, Boolean.TRUE); + return authService.getJWTTokenBean(userEntity, Boolean.TRUE, loginAttemptEntity.getId()); } private BeneficiaryEntity createBeneficiary(RoleEntity roleEntity, UserReq userReq, HubEntity hub) { diff --git a/src/main/java/net/gepafin/tendermanagement/entities/UserActionEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/UserActionEntity.java new file mode 100644 index 00000000..019f0317 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/entities/UserActionEntity.java @@ -0,0 +1,43 @@ +package net.gepafin.tendermanagement.entities; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Table; +import lombok.Data; + +@Data +@Entity +@Table(name = "user_action") +public class UserActionEntity extends BaseEntity { + + @Column(name = "USER_ID") + private Long userId; + + @Column(name = "ACTION_TYPE") + private String actionType; + + @Column(name = "REQUEST_BODY") + private String requestBody; + + @Column(name = "LOGIN_ATTEMPT_ID") + private Long loginAttemptId; + + @Column(name = "IP_ADDRESS") + private String ipAddress; + + @Column(name = "METHOD_TYPE") + private String methodType; + + @Column(name = "HUB_ID") + private Long hubId; + + @Column(name = "URL") + private String url; + + @Column(name = "ACTION_CONTEXT") + private String actionContext; + + @Column(name = "RESPONSE") + private Object response; + +} \ No newline at end of file diff --git a/src/main/java/net/gepafin/tendermanagement/entities/VersionHistoryEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/VersionHistoryEntity.java new file mode 100644 index 00000000..7a544363 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/entities/VersionHistoryEntity.java @@ -0,0 +1,33 @@ +package net.gepafin.tendermanagement.entities; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Table; +import lombok.Data; + +@Data +@Entity +@Table(name = "version_history") +public class VersionHistoryEntity extends BaseEntity { + + @Column(name = "OLD_DATA", columnDefinition = "LONGTEXT") + private String oldData; + + @Column(name = "NEW_DATA", columnDefinition = "LONGTEXT") + private String newData; + + @Column(name = "TABLE_NAME") + private String tableName; + + @Column(name = "ACTION_TYPE") + private String actionType; + + @Column(name = "RECORD_ID") + private Long recordId; + + @Column(name = "USER_ACTION_ID") + private Long userActionId; + + @Column(name = "USER_ID") + private Long userId; +} diff --git a/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java new file mode 100644 index 00000000..be56c433 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java @@ -0,0 +1,20 @@ +package net.gepafin.tendermanagement.enums; + +import com.fasterxml.jackson.annotation.JsonValue; + +public enum UserActionContextEnum { + CREATE_CALL("CREATE_CALL"),; + + private final String value; + + UserActionContextEnum(String value) { + + this.value = value; + } + + @JsonValue + public String getValue() { + + return value; + } +} diff --git a/src/main/java/net/gepafin/tendermanagement/enums/UserActionLogsEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/UserActionLogsEnum.java new file mode 100644 index 00000000..65f2243d --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/enums/UserActionLogsEnum.java @@ -0,0 +1,20 @@ +package net.gepafin.tendermanagement.enums; + +import com.fasterxml.jackson.annotation.JsonValue; + +public enum UserActionLogsEnum { + LOGIN("LOGIN"), LOGOUT("LOGOUT"), UPDATE("UPDATE"), DELETE("DELETE"), VIEW("VIEW"), INSERT("INSERT"); + + private final String value; + + UserActionLogsEnum(String value) { + + this.value = value; + } + + @JsonValue + public String getValue() { + + return value; + } +} diff --git a/src/main/java/net/gepafin/tendermanagement/enums/VersionActionTypeEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/VersionActionTypeEnum.java new file mode 100644 index 00000000..27d2a55d --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/enums/VersionActionTypeEnum.java @@ -0,0 +1,20 @@ +package net.gepafin.tendermanagement.enums; + +import com.fasterxml.jackson.annotation.JsonValue; + +public enum VersionActionTypeEnum { + UPDATE("UPDATE"), DELETE("DELETE"), SOFT_DELETE("SOFT_DELETE"), INSERT("INSERT"); + + private final String value; + + VersionActionTypeEnum(String value) { + + this.value = value; + } + + @JsonValue + public String getValue() { + + return value; + } +} diff --git a/src/main/java/net/gepafin/tendermanagement/model/request/UserActionRequest.java b/src/main/java/net/gepafin/tendermanagement/model/request/UserActionRequest.java new file mode 100644 index 00000000..0b28f70b --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/model/request/UserActionRequest.java @@ -0,0 +1,12 @@ +package net.gepafin.tendermanagement.model.request; + +import jakarta.servlet.http.HttpServletRequest; +import lombok.Data; +import net.gepafin.tendermanagement.enums.UserActionLogsEnum; + +@Data +public class UserActionRequest { + private HttpServletRequest request; + private UserActionLogsEnum actionType; + private String actionContext; +} diff --git a/src/main/java/net/gepafin/tendermanagement/model/request/VersionHistoryRequest.java b/src/main/java/net/gepafin/tendermanagement/model/request/VersionHistoryRequest.java new file mode 100644 index 00000000..c09bad29 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/model/request/VersionHistoryRequest.java @@ -0,0 +1,17 @@ +package net.gepafin.tendermanagement.model.request; + +import jakarta.servlet.http.HttpServletRequest; +import lombok.Data; +import net.gepafin.tendermanagement.entities.BaseEntity; +import net.gepafin.tendermanagement.enums.VersionActionTypeEnum; + +@Data +public class VersionHistoryRequest { + private BaseEntity oldData; + private BaseEntity newData; + private VersionActionTypeEnum actionType; + private HttpServletRequest request; + private Long userActionId; + private Long recordId; + private String tableName; +} diff --git a/src/main/java/net/gepafin/tendermanagement/model/util/LogResponse.java b/src/main/java/net/gepafin/tendermanagement/model/util/LogResponse.java new file mode 100644 index 00000000..e7b26b04 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/model/util/LogResponse.java @@ -0,0 +1,28 @@ +package net.gepafin.tendermanagement.model.util; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import net.gepafin.tendermanagement.web.rest.api.errors.Status; + +import java.io.Serial; +import java.io.Serializable; + +@JsonIgnoreProperties(ignoreUnknown = true) +@Getter +@Setter +@AllArgsConstructor +@NoArgsConstructor +public class LogResponse implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + private Integer status; + + private String statusCode; + + private String message; +} \ No newline at end of file diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/UserActionsRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/UserActionsRepository.java new file mode 100644 index 00000000..ba651c6f --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/repositories/UserActionsRepository.java @@ -0,0 +1,9 @@ +package net.gepafin.tendermanagement.repositories; + +import net.gepafin.tendermanagement.entities.UserActionEntity; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface UserActionsRepository extends JpaRepository { +} diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/VersionHistoryRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/VersionHistoryRepository.java new file mode 100644 index 00000000..059024ab --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/repositories/VersionHistoryRepository.java @@ -0,0 +1,9 @@ +package net.gepafin.tendermanagement.repositories; + +import net.gepafin.tendermanagement.entities.VersionHistoryEntity; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface VersionHistoryRepository extends JpaRepository { +} diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/AuthenticationService.java b/src/main/java/net/gepafin/tendermanagement/service/impl/AuthenticationService.java index ddd74035..30edb908 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/AuthenticationService.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/AuthenticationService.java @@ -103,7 +103,7 @@ public class AuthenticationService { createFailedLoginAttempt(loginAttemptEntity, e.getMessage()); throw e; } - return getJWTTokenBean(user, loginReq.getRememberMe()); + return getJWTTokenBean(user, loginReq.getRememberMe(), loginAttemptEntity.getId()); } public LoginAttemptEntity prepareLoginAttemptEntity(LoginReq loginUserReq, HttpServletRequest request) { @@ -126,10 +126,10 @@ public class AuthenticationService { loginAttemptEntity.setErrorMsg(errorMsg); loginAttemptDao.createLoginAttempt(loginAttemptEntity); } - public JWTToken getJWTTokenBean(UserEntity user, Boolean rememberMe) { + public JWTToken getJWTTokenBean(UserEntity user, Boolean rememberMe, Long loginAttemptId) { user.setLastLogin(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); - userRepository.save(user); - String token = tokenProvider.createToken(rememberMe, user); + user = userRepository.save(user); + String token = tokenProvider.createToken(rememberMe, user, loginAttemptId); log.info("JWT token generated for email: {}", user.getEmail()); RoleResponseBean roleResponseBean = roleDao.convertRoleEntityToRoleResponse(user.getRoleEntity()); @@ -215,7 +215,7 @@ public class AuthenticationService { loginReq.setEmail(userEntity.getEmail()); loginAttemptEntity = prepareLoginAttemptEntity(loginReq, request); loginAttemptEntity.setUserId(userEntity.getId()); - return getJWTTokenBean(userEntity, Boolean.TRUE); + return getJWTTokenBean(userEntity, Boolean.TRUE, loginAttemptEntity.getId()); } catch (Exception e) { log.info("Authentication login failed for email: {}",e.getMessage()); loginAttemptEntity.setUserId(userId); diff --git a/src/main/java/net/gepafin/tendermanagement/util/IpAddressUtils.java b/src/main/java/net/gepafin/tendermanagement/util/IpAddressUtils.java new file mode 100644 index 00000000..e4673039 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/util/IpAddressUtils.java @@ -0,0 +1,45 @@ +package net.gepafin.tendermanagement.util; + +import jakarta.servlet.http.HttpServletRequest; + +import java.util.regex.Pattern; + +public class IpAddressUtils { + + private static final Pattern IPV4_PATTERN = Pattern.compile("^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$"); + + private static final Pattern IPV6_PATTERN = Pattern.compile( + "([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|" + "([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|" + "([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|" + "([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|" + ":((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|" + "::(ffff(:0{1,4}){0,1}:){0,1}(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3,3}" + "([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])|([0-9a-fA-F]{1,4}:){1,4}:" + "(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3,3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])"); + + public static String getClientIp(HttpServletRequest request) { + + String ipAddress = null; + + String[] headers = { "X-Forwarded-For", "X-Real-IP", "Proxy-Client-IP", "WL-Proxy-Client-IP", "HTTP_CLIENT_IP", "HTTP_X_FORWARDED_FOR" }; + + for (String header : headers) { + ipAddress = request.getHeader(header); + if (ipAddress != null && !ipAddress.isEmpty() && !"unknown".equalsIgnoreCase(ipAddress)) { + ipAddress = ipAddress.split(",")[0].trim(); + break; + } + } + if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) { + ipAddress = request.getRemoteAddr(); + } + if ("0:0:0:0:0:0:0:1".equals(ipAddress) || "127.0.0.1".equals(ipAddress)) { + ipAddress = "127.0.0.1"; + } + if (isValidIpAddress(ipAddress)) { + return ipAddress; + } else { + return "Invalid IP"; + } + } + + private static boolean isValidIpAddress(String ipAddress) { + + return IPV4_PATTERN.matcher(ipAddress).matches() || IPV6_PATTERN.matcher(ipAddress).matches(); + } +} + diff --git a/src/main/java/net/gepafin/tendermanagement/util/LoggingUtil.java b/src/main/java/net/gepafin/tendermanagement/util/LoggingUtil.java new file mode 100644 index 00000000..2fa50b3a --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/util/LoggingUtil.java @@ -0,0 +1,149 @@ +package net.gepafin.tendermanagement.util; + +import com.fasterxml.jackson.databind.ObjectMapper; +import io.jsonwebtoken.Claims; +import jakarta.persistence.Table; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import lombok.extern.slf4j.Slf4j; +import net.gepafin.tendermanagement.config.CachedBodyHttpServletRequest; +import net.gepafin.tendermanagement.config.jwt.TokenProvider; +import net.gepafin.tendermanagement.constants.GepafinConstant; +import net.gepafin.tendermanagement.entities.UserActionEntity; +import net.gepafin.tendermanagement.entities.UserEntity; +import net.gepafin.tendermanagement.entities.VersionHistoryEntity; +import net.gepafin.tendermanagement.model.request.UserActionRequest; +import net.gepafin.tendermanagement.model.request.VersionHistoryRequest; +import net.gepafin.tendermanagement.model.util.LogResponse; +import net.gepafin.tendermanagement.repositories.UserActionsRepository; +import net.gepafin.tendermanagement.repositories.VersionHistoryRepository; +import net.gepafin.tendermanagement.service.UserService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.context.annotation.RequestScope; + +@Slf4j +@Component +@RequestScope +public class LoggingUtil { + + @Autowired + private UserActionsRepository userActionsRepository; + + @Autowired + private VersionHistoryRepository versionHistoryRepository; + + @Autowired + private UserService userService; + + @Autowired + TokenProvider tokenProvider; + + public UserActionEntity logUserAction(UserActionRequest userActionRequest) { + UserActionEntity userAction = new UserActionEntity(); + try { + String token = tokenProvider.extractTokenFromRequest(userActionRequest.getRequest()); + Claims claims = tokenProvider.getClaimsFromToken(token); + Long userId = claims.get(GepafinConstant.USER_ID, Long.class); + Long loginAttemptId = claims.get(GepafinConstant.LOGIN_ATTEMPT_ID, Long.class); + UserEntity userEntity = userService.validateUser(userId); + + String requestBody = null; + if (userActionRequest.getRequest() instanceof CachedBodyHttpServletRequest cachedRequest) { + requestBody = cachedRequest.getCachedBodyAsString(); + } + userAction.setActionType(userActionRequest.getActionType().getValue()); + userAction.setUserId(userId); + userAction.setActionContext(userActionRequest.getActionContext()); + userAction.setMethodType(userActionRequest.getRequest().getMethod()); + userAction.setHubId(userEntity.getHub().getId()); + userAction.setUrl(userActionRequest.getRequest().getRequestURI()); + userAction.setLoginAttemptId(loginAttemptId); + userAction.setIpAddress(IpAddressUtils.getClientIp(userActionRequest.getRequest())); + userAction.setRequestBody(requestBody); + userAction.setResponse(null); + userActionsRepository.save(userAction); + userActionRequest.getRequest().setAttribute(GepafinConstant.USER_ACTION_ID, userAction.getId()); + } catch (Exception e) { + log.error("Error logging user action: {}", e.getMessage(), e); + } + return userAction; + } + +// @Transactional +// public UserActionEntity updateUserAction(HttpServletResponse response, UserActionEntity userAction) { +// try { +// String requestBody = null; +// if (userAction. instanceof CachedBodyHttpServletRequest cachedRequest) { +// requestBody = cachedRequest.getCachedBodyAsString(); +// } +// +// LogResponse logResponse = new LogResponse<>(); +// logResponse.setStatus(response.getStatus()); +// logResponse.setStatusCode(String.valueOf(response.getStatus())); +// logResponse.setMessage("SUCCESS"); +// +// String serializedResponse; +// try { +// ObjectMapper objectMapper = new ObjectMapper(); +// serializedResponse = objectMapper.writeValueAsString(logResponse); +// } catch (Exception e) { +// serializedResponse = "Error serializing LogResponse: " + e.getMessage(); +// } +// +// userAction.setResponse(serializedResponse); +// userActionsRepository.save(userAction); +// } catch (Exception e) { +// log.error("Error updating user action: {}", e.getMessage(), e); +// } +// return userAction; +// } + + public void logVersionHistory(VersionHistoryRequest versionHistoryRequest) { + try { + VersionHistoryEntity history = new VersionHistoryEntity(); + String token = tokenProvider.extractTokenFromRequest(versionHistoryRequest.getRequest()); + Claims claims = tokenProvider.getClaimsFromToken(token); + Long userId = claims.get(GepafinConstant.USER_ID, Long.class); + String oldData = Utils.convertEntityToJsonForLogging(versionHistoryRequest.getOldData()); + String newData = Utils.convertEntityToJsonForLogging(versionHistoryRequest.getNewData()); + history.setUserActionId(versionHistoryRequest.getUserActionId()); + history.setActionType(versionHistoryRequest.getActionType().getValue()); + history.setOldData(oldData); + history.setNewData(newData); + history.setRecordId(versionHistoryRequest.getRecordId()); + history.setTableName(versionHistoryRequest.getTableName()); + history.setUserId(userId); + versionHistoryRepository.save(history); + } catch (Exception e) { + log.error("Error logging version history: {}", e.getMessage(), e); + } + } + + public String getTableName(Class entityClass) { + try { + if (entityClass.isAnnotationPresent(Table.class)) { + Table tableAnnotation = entityClass.getAnnotation(Table.class); + return tableAnnotation.name(); + } + } catch (Exception e) { + log.error("Error retrieving table name: {}", e.getMessage(), e); + } + return null; + } + + public void addVersionHistory(VersionHistoryRequest versionHistoryRequest) { + try { + Long userActionId = (Long) versionHistoryRequest.getRequest().getAttribute(GepafinConstant.USER_ACTION_ID); + Long recordId = versionHistoryRequest.getNewData().getId(); + String tableName = getTableName(versionHistoryRequest.getNewData().getClass()); + versionHistoryRequest.setRecordId(recordId); + versionHistoryRequest.setUserActionId(userActionId); + versionHistoryRequest.setTableName(tableName); + logVersionHistory(versionHistoryRequest); + } catch (Exception e) { + log.error("Error adding version history: {}", e.getMessage(), e); + } + } +} diff --git a/src/main/java/net/gepafin/tendermanagement/util/Utils.java b/src/main/java/net/gepafin/tendermanagement/util/Utils.java index 26f049ef..76f4fac6 100644 --- a/src/main/java/net/gepafin/tendermanagement/util/Utils.java +++ b/src/main/java/net/gepafin/tendermanagement/util/Utils.java @@ -5,20 +5,19 @@ import java.lang.reflect.Field; import java.lang.reflect.Type; import java.nio.charset.StandardCharsets; import java.security.SecureRandom; -import java.text.DecimalFormat; import java.text.NumberFormat; import java.text.ParseException; import java.text.SimpleDateFormat; -import java.time.LocalDate; -import java.time.format.DateTimeFormatter; -import java.time.format.DateTimeParseException; import java.util.*; import java.util.function.Consumer; import java.util.function.Supplier; import java.util.regex.Pattern; import java.util.stream.Collectors; -import com.itextpdf.styledxmlparser.jsoup.Jsoup; +import com.fasterxml.jackson.annotation.JsonAutoDetect; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.PropertyAccessor; +import com.fasterxml.jackson.databind.SerializationFeature; import jakarta.servlet.http.HttpServletRequest; import net.gepafin.tendermanagement.constants.GepafinConstant; import org.apache.commons.collections4.MapUtils; @@ -515,4 +514,36 @@ public class Utils { } return null; } + + public static String convertEntityToJsonForLogging(Object entity) { + + if(entity == null){ + return null; + } + try { + return mapper.writeValueAsString(entity); + } catch (JsonProcessingException e) { + e.printStackTrace(); + return null; + } + } + + @JsonIgnoreProperties({ "childEntities", "relatedData", "otherRelations" }) + private abstract static class IgnoreChildEntities { + } + + public static T getClonedEntityForData(T entity) { + + if (entity == null) { + return null; + } + try { + String json = mapper.writeValueAsString(entity); + @SuppressWarnings("unchecked") T clonedEntity = (T) mapper.readValue(json, entity.getClass()); + return clonedEntity; + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException("Failed to clone entity", e); + } + } } diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/CallApiController.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/CallApiController.java index 32c89055..40b3679f 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/CallApiController.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/CallApiController.java @@ -2,7 +2,13 @@ package net.gepafin.tendermanagement.web.rest.api.impl; import java.util.List; +import lombok.extern.slf4j.Slf4j; import net.gepafin.tendermanagement.enums.CallStatusEnum; +import net.gepafin.tendermanagement.enums.UserActionContextEnum; +import net.gepafin.tendermanagement.enums.UserActionLogsEnum; +import net.gepafin.tendermanagement.model.request.UserActionRequest; +import net.gepafin.tendermanagement.repositories.UserActionsRepository; +import net.gepafin.tendermanagement.util.LoggingUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; @@ -33,11 +39,22 @@ public class CallApiController implements CallApi { @Autowired private CallService callService; + @Autowired + private LoggingUtil loggingUtil; + + @Autowired + private UserActionsRepository userActionsRepository; @Override - @Transactional(rollbackFor=Exception.class) + @Transactional(rollbackFor = Exception.class) public ResponseEntity> createCallStep1(HttpServletRequest request, CreateCallRequestStep1 createCallRequest) { - CallResponse createCallResponseBean = callService.createCallStep1(request, createCallRequest); + + UserActionRequest userActionRequest = new UserActionRequest(); + userActionRequest.setRequest(request); + userActionRequest.setActionType(UserActionLogsEnum.INSERT); + userActionRequest.setActionContext(UserActionContextEnum.CREATE_CALL.getValue()); + loggingUtil.logUserAction(userActionRequest); + CallResponse createCallResponseBean = callService.createCallStep1(request, createCallRequest); return ResponseEntity.status(HttpStatus.CREATED) .body(new Response<>(createCallResponseBean, Status.SUCCESS, Translator.toLocale(GepafinConstant.CALL_CREATED_SUCCESSFULLY_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 15dad70f..b4c88aa2 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 @@ -1732,4 +1732,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From f66ddf6e47894e89e47ce5a04b2c60f18006ae7d Mon Sep 17 00:00:00 2001 From: rajesh Date: Wed, 20 Nov 2024 14:40:32 +0530 Subject: [PATCH 02/43] updated code --- .../gepafin/tendermanagement/dao/CallDao.java | 102 +++++++++--------- .../gepafin/tendermanagement/dao/FaqDao.java | 20 ++-- .../tendermanagement/dao/LookUpDataDao.java | 9 +- .../model/request/UserActionRequest.java | 5 +- .../model/request/VersionHistoryRequest.java | 5 +- .../tendermanagement/util/LoggingUtil.java | 15 ++- .../web/rest/api/impl/CallApiController.java | 19 ++-- 7 files changed, 83 insertions(+), 92 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java b/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java index 6aa766e1..3a2dd9e4 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java @@ -109,9 +109,7 @@ public class CallDao { CallEntity callEntity = convertToCallEntity(createCallRequest, userEntity); updateFaq(createCallRequest.getFaq(), callEntity, userEntity,LookUpDataTypeEnum.FAQ); - - convertLookUpDataEntities(createCallRequest.getAimedTo(), callEntity, - LookUpDataTypeEnum.AIMED_TO); + updateLookUpData(callEntity, createCallRequest.getAimedTo(), LookUpDataTypeEnum.AIMED_TO); CallResponse createCallResponseBean = getCallResponseBean(callEntity); createCallResponseBean.setCurrentStep(GepafinConstant.STEP_1); @@ -152,7 +150,6 @@ public class CallDao { public CallEntity convertToCallEntity(CreateCallRequestStep1 createCallRequest, UserEntity userEntity) { CallEntity callEntity = new CallEntity(); - VersionHistoryRequest versionHistoryRequest = new VersionHistoryRequest(); // validateCallEntity(createCallRequest); RegionEntity region = regionRepository.findById(createCallRequest.getRegionId()) .orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND, @@ -189,11 +186,9 @@ public class CallDao { callEntity.setEndTime(DateTimeUtil.parseTime(createCallRequest.getEndTime())); callEntity.setHub(userEntity.getHub()); callEntity = callRepository.save(callEntity); - versionHistoryRequest.setOldData(null); - versionHistoryRequest.setNewData(callEntity); - versionHistoryRequest.setRequest(request); - versionHistoryRequest.setActionType(VersionActionTypeEnum.INSERT); - loggingUtil.addVersionHistory(versionHistoryRequest); + + /** This code is responsible for adding a version history log for the "Create Call" operation. **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.INSERT).oldData(null).newData(callEntity).build()); return callEntity; } @@ -211,15 +206,7 @@ public class CallDao { List evaluationCriteriaEntities = criteriaReqList.stream() .map(req -> convertToEvaluationCriteriaEntity(req, callEntity, type)).collect(Collectors.toList()); - List data = evaluationCriteriaRepository.saveAll(evaluationCriteriaEntities); - data.forEach(entity -> { - VersionHistoryRequest versionHistoryRequest = new VersionHistoryRequest(); - versionHistoryRequest.setOldData(null); - versionHistoryRequest.setNewData(entity); - versionHistoryRequest.setRequest(request); - versionHistoryRequest.setActionType(VersionActionTypeEnum.INSERT); - loggingUtil.addVersionHistory(versionHistoryRequest); - }); + return evaluationCriteriaEntities; } @@ -237,22 +224,31 @@ public class CallDao { private EvaluationCriteriaEntity convertToEvaluationCriteriaEntity(EvaluationCriteriaReq criteriaReq, CallEntity callEntity, LookUpDataTypeEnum type) { EvaluationCriteriaEntity criteriaEntity = null; + EvaluationCriteriaEntity oldCriteriaEntity = null; + VersionActionTypeEnum actionType = VersionActionTypeEnum.INSERT; LookUpDataEntity lookupDataEntity = lookUpDataService.getOrCreateLookUpDataEntity(criteriaReq, type); if (criteriaReq.getId() != null && criteriaReq.getId() > 0) { criteriaEntity = evaluationCriteriaRepository.findById(criteriaReq.getId()) .orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.EVALUATION_CRITERIA_NOT_FOUND))); + oldCriteriaEntity = Utils.getClonedEntityForData(oldCriteriaEntity); + actionType = VersionActionTypeEnum.UPDATE; } else { criteriaEntity = new EvaluationCriteriaEntity(); criteriaEntity.setCall(callEntity); criteriaEntity.setLookupData(lookupDataEntity); criteriaEntity.setScore(0L); criteriaEntity.setIsDeleted(false); + actionType = VersionActionTypeEnum.INSERT; } setIfUpdated(criteriaEntity::getScore, criteriaEntity::setScore, criteriaReq.getScore()); if (Boolean.FALSE.equals(criteriaEntity.getLookupData().getId().equals(lookupDataEntity.getId()))) { criteriaEntity.setLookupData(lookupDataEntity); } + criteriaEntity = evaluationCriteriaRepository.save(criteriaEntity) ; + + /** This code is responsible for adding a version history log for the "create or update evaluation criteria" operation **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(actionType).oldData(oldCriteriaEntity).newData(criteriaEntity).build()); return criteriaEntity; } @@ -402,38 +398,37 @@ public class CallDao { return createCallResponseBean; } - public List convertLookUpDataEntities(List lookUpData, CallEntity callEntity, - LookUpDataEntity.LookUpDataTypeEnum type) { - if(lookUpData == null) { - return null; - } - List lookUpDataEntities = lookUpData.stream() - .map(req -> lookUpDataService.getOrCreateLookUpDataEntity(req, type)).collect(Collectors.toList()); +// public List convertLookUpDataEntities(List lookUpData, CallEntity callEntity, +// LookUpDataEntity.LookUpDataTypeEnum type) { +// if(lookUpData == null) { +// return null; +// } +// List lookUpDataEntities = lookUpData.stream() +// .map(req -> lookUpDataService.getOrCreateLookUpDataEntity(req, type)).collect(Collectors.toList()); +// +// return createCallTargetAudienceCheckList(callEntity, lookUpDataEntities); +// } - return createCallTargetAudienceCheckList(callEntity, lookUpDataEntities); - } - - private List createCallTargetAudienceCheckList(CallEntity callEntity, - List lookUpDataEntities) { - List lookUpDataResponses = new ArrayList<>(); - VersionHistoryRequest versionHistoryRequest = new VersionHistoryRequest(); - for (LookUpDataEntity lookUpDataEntity : lookUpDataEntities) { - CallTargetAudienceChecklistEntity callTargetAudienceChecklistEntity = new CallTargetAudienceChecklistEntity(); - callTargetAudienceChecklistEntity.setIsValidated(false); - callTargetAudienceChecklistEntity.setLookupData(lookUpDataEntity); - callTargetAudienceChecklistEntity.setCall(callEntity); - callTargetAudienceChecklistEntity.setIsDeleted(false); - callTargetAudienceChecklistEntity = callTargetAudienceChecklistRepository - .save(callTargetAudienceChecklistEntity); - versionHistoryRequest.setOldData(null); - versionHistoryRequest.setNewData(callTargetAudienceChecklistEntity); - versionHistoryRequest.setActionType(VersionActionTypeEnum.INSERT); - versionHistoryRequest.setRequest(request); - loggingUtil.addVersionHistory(versionHistoryRequest); - lookUpDataResponses.add(convertToLookUpDataResponseBean(callTargetAudienceChecklistEntity)); - } - return lookUpDataResponses; - } +// private List createCallTargetAudienceCheckList(CallEntity callEntity, +// List lookUpDataEntities) { +// List lookUpDataResponses = new ArrayList<>(); +// for (LookUpDataEntity lookUpDataEntity : lookUpDataEntities) { +// CallTargetAudienceChecklistEntity callTargetAudienceChecklistEntity = new CallTargetAudienceChecklistEntity(); +// callTargetAudienceChecklistEntity.setIsValidated(false); +// callTargetAudienceChecklistEntity.setLookupData(lookUpDataEntity); +// callTargetAudienceChecklistEntity.setCall(callEntity); +// callTargetAudienceChecklistEntity.setIsDeleted(false); +// callTargetAudienceChecklistEntity = callTargetAudienceChecklistRepository +// .save(callTargetAudienceChecklistEntity); +// versionHistoryRequest.setOldData(null); +// versionHistoryRequest.setNewData(callTargetAudienceChecklistEntity); +// versionHistoryRequest.setActionType(VersionActionTypeEnum.INSERT); +// versionHistoryRequest.setRequest(request); +// loggingUtil.addVersionHistory(versionHistoryRequest); +// lookUpDataResponses.add(convertToLookUpDataResponseBean(callTargetAudienceChecklistEntity)); +// } +// return lookUpDataResponses; +// } public LookUpDataResponse convertToLookUpDataResponseBean( CallTargetAudienceChecklistEntity callTargetAudienceChecklistEntity) { @@ -604,6 +599,8 @@ public class CallDao { private void createOrUpdateCallTargetAudienceChecklist(LookUpDataReq lookUpDataReq, CallEntity callEntity, LookUpDataTypeEnum type) { CallTargetAudienceChecklistEntity checklistEntity = null; + CallTargetAudienceChecklistEntity oldChecklistEntity = null; + VersionActionTypeEnum actionType = VersionActionTypeEnum.INSERT; LookUpDataEntity lookupDataEntity = lookUpDataService.getOrCreateLookUpDataEntity(lookUpDataReq, type); if (lookUpDataReq.getId() != null && lookUpDataReq.getId() > 0) { checklistEntity = callTargetAudienceChecklistRepository.findById(lookUpDataReq.getId()) @@ -613,15 +610,20 @@ public class CallDao { if (Boolean.FALSE.equals(checklistEntity.getLookupData().getId().equals(lookupDataEntity.getId()))) { checklistEntity.setLookupData(lookupDataEntity); } + actionType = VersionActionTypeEnum.UPDATE; } else { checklistEntity = new CallTargetAudienceChecklistEntity(); checklistEntity.setCall(callEntity); checklistEntity.setLookupData(lookupDataEntity); checklistEntity.setIsValidated(false); checklistEntity.setIsDeleted(false); + actionType = VersionActionTypeEnum.INSERT; } - callTargetAudienceChecklistRepository.save(checklistEntity); + checklistEntity = callTargetAudienceChecklistRepository.save(checklistEntity); + + /** This code is responsible for adding a version history log for the "create or update aimedTo Checklist" operation **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(actionType).oldData(oldChecklistEntity).newData(checklistEntity).build()); } private void softDeleteCallTargetAudienceChecklist( diff --git a/src/main/java/net/gepafin/tendermanagement/dao/FaqDao.java b/src/main/java/net/gepafin/tendermanagement/dao/FaqDao.java index fb6050da..ecfb77bd 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/FaqDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/FaqDao.java @@ -103,13 +103,14 @@ public class FaqDao { public FaqEntity createOrUpdateFaqEntity(FaqReq faqReq, CallEntity callEntity, UserEntity userEntity, LookUpDataTypeEnum type) { FaqEntity faqEntity = null; - FaqEntity oldFaqData = null; - VersionHistoryRequest versionHistoryRequest = new VersionHistoryRequest(); + FaqEntity oldFaqEntity = null; + VersionActionTypeEnum actionType = VersionActionTypeEnum.INSERT; if (isExistingFaq(faqReq)) { faqEntity = faqRepository.findByIdAndCallIdAndIsDeletedFalse(faqReq.getId(), callEntity.getId()) .orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.FAQ_NOT_FOUND))); - oldFaqData = Utils.getClonedEntityForData(faqEntity); + oldFaqEntity = Utils.getClonedEntityForData(faqEntity); + actionType = VersionActionTypeEnum.UPDATE; } else { if (Boolean.FALSE.equals(userEntity.getRoleEntity().getRoleType().equals(RoleStatusEnum.ROLE_BENEFICIARY.getValue()))) { lookUpDataService.getOrCreateLookUpDataEntity(faqReq, type); @@ -119,6 +120,7 @@ public class FaqDao { faqEntity.setUser(userEntity); faqEntity.setIsVisible(false); faqEntity.setIsDeleted(false); + actionType = VersionActionTypeEnum.INSERT; } if (faqReq.getResponse() != null && (faqEntity.getResponse() == null || Boolean.FALSE.equals(faqReq.getResponse().equals(faqEntity.getResponse())))) { @@ -128,13 +130,11 @@ public class FaqDao { setIfUpdated(faqEntity::getValue, faqEntity::setValue, faqReq.getValue()); setIfUpdated(faqEntity::getResponse, faqEntity::setResponse, faqReq.getResponse()); setIfUpdated(faqEntity::getIsVisible, faqEntity::setIsVisible, faqReq.getIsVisible()); - FaqEntity newFaqData = faqRepository.save(faqEntity); - versionHistoryRequest.setOldData(oldFaqData); - versionHistoryRequest.setNewData(newFaqData); - versionHistoryRequest.setActionType(VersionActionTypeEnum.INSERT); - versionHistoryRequest.setRequest(request); - loggingUtil.addVersionHistory(versionHistoryRequest); - return newFaqData; + faqEntity = faqRepository.save(faqEntity); + + /** This code is responsible for adding a version history log for the "create or update faq" operation **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(actionType).oldData(oldFaqEntity).newData(faqEntity).build()); + return faqEntity; } private boolean isExistingFaq(FaqReq faqReq) { diff --git a/src/main/java/net/gepafin/tendermanagement/dao/LookUpDataDao.java b/src/main/java/net/gepafin/tendermanagement/dao/LookUpDataDao.java index f9a7f4e2..b1faf04c 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/LookUpDataDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/LookUpDataDao.java @@ -104,18 +104,15 @@ public class LookUpDataDao { if (req.getLookUpDataId() == null || req.getLookUpDataId().equals(0L)) { LookUpDataEntity newEntity = new LookUpDataEntity(); - VersionHistoryRequest versionHistoryRequest = new VersionHistoryRequest(); newEntity.setTitle(req.getTitle()); newEntity.setValue(req.getValue()); newEntity.setResponse(req.getResponse()); newEntity.setType(type.getValue()); validateLookUpDataEntity(newEntity); LookUpDataEntity lookUpDataEntity = lookUpDataRepository.save(newEntity); - versionHistoryRequest.setOldData(null); - versionHistoryRequest.setNewData(lookUpDataEntity); - versionHistoryRequest.setActionType(VersionActionTypeEnum.INSERT); - versionHistoryRequest.setRequest(request); - loggingUtil.addVersionHistory(versionHistoryRequest); + + /** This code is responsible for adding a version history log for the "create or update lookup data" operation **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.INSERT).oldData(null).newData(lookUpDataEntity).build()); return lookUpDataEntity; } diff --git a/src/main/java/net/gepafin/tendermanagement/model/request/UserActionRequest.java b/src/main/java/net/gepafin/tendermanagement/model/request/UserActionRequest.java index 0b28f70b..bdf6249b 100644 --- a/src/main/java/net/gepafin/tendermanagement/model/request/UserActionRequest.java +++ b/src/main/java/net/gepafin/tendermanagement/model/request/UserActionRequest.java @@ -1,12 +1,15 @@ package net.gepafin.tendermanagement.model.request; import jakarta.servlet.http.HttpServletRequest; +import lombok.Builder; import lombok.Data; +import net.gepafin.tendermanagement.enums.UserActionContextEnum; import net.gepafin.tendermanagement.enums.UserActionLogsEnum; @Data +@Builder public class UserActionRequest { private HttpServletRequest request; private UserActionLogsEnum actionType; - private String actionContext; + private UserActionContextEnum actionContext; } diff --git a/src/main/java/net/gepafin/tendermanagement/model/request/VersionHistoryRequest.java b/src/main/java/net/gepafin/tendermanagement/model/request/VersionHistoryRequest.java index c09bad29..c5e817d4 100644 --- a/src/main/java/net/gepafin/tendermanagement/model/request/VersionHistoryRequest.java +++ b/src/main/java/net/gepafin/tendermanagement/model/request/VersionHistoryRequest.java @@ -1,17 +1,16 @@ package net.gepafin.tendermanagement.model.request; import jakarta.servlet.http.HttpServletRequest; +import lombok.Builder; import lombok.Data; import net.gepafin.tendermanagement.entities.BaseEntity; import net.gepafin.tendermanagement.enums.VersionActionTypeEnum; @Data +@Builder public class VersionHistoryRequest { private BaseEntity oldData; private BaseEntity newData; private VersionActionTypeEnum actionType; private HttpServletRequest request; - private Long userActionId; - private Long recordId; - private String tableName; } diff --git a/src/main/java/net/gepafin/tendermanagement/util/LoggingUtil.java b/src/main/java/net/gepafin/tendermanagement/util/LoggingUtil.java index 2fa50b3a..ecab52e4 100644 --- a/src/main/java/net/gepafin/tendermanagement/util/LoggingUtil.java +++ b/src/main/java/net/gepafin/tendermanagement/util/LoggingUtil.java @@ -55,7 +55,7 @@ public class LoggingUtil { } userAction.setActionType(userActionRequest.getActionType().getValue()); userAction.setUserId(userId); - userAction.setActionContext(userActionRequest.getActionContext()); + userAction.setActionContext(userActionRequest.getActionContext().getValue()); userAction.setMethodType(userActionRequest.getRequest().getMethod()); userAction.setHubId(userEntity.getHub().getId()); userAction.setUrl(userActionRequest.getRequest().getRequestURI()); @@ -100,7 +100,7 @@ public class LoggingUtil { // return userAction; // } - public void logVersionHistory(VersionHistoryRequest versionHistoryRequest) { + public void logVersionHistory(VersionHistoryRequest versionHistoryRequest, Long recordId, Long userActionId, String tableName) { try { VersionHistoryEntity history = new VersionHistoryEntity(); String token = tokenProvider.extractTokenFromRequest(versionHistoryRequest.getRequest()); @@ -108,12 +108,12 @@ public class LoggingUtil { Long userId = claims.get(GepafinConstant.USER_ID, Long.class); String oldData = Utils.convertEntityToJsonForLogging(versionHistoryRequest.getOldData()); String newData = Utils.convertEntityToJsonForLogging(versionHistoryRequest.getNewData()); - history.setUserActionId(versionHistoryRequest.getUserActionId()); + history.setUserActionId(userActionId); history.setActionType(versionHistoryRequest.getActionType().getValue()); history.setOldData(oldData); history.setNewData(newData); - history.setRecordId(versionHistoryRequest.getRecordId()); - history.setTableName(versionHistoryRequest.getTableName()); + history.setRecordId(recordId); + history.setTableName(tableName); history.setUserId(userId); versionHistoryRepository.save(history); } catch (Exception e) { @@ -138,10 +138,7 @@ public class LoggingUtil { Long userActionId = (Long) versionHistoryRequest.getRequest().getAttribute(GepafinConstant.USER_ACTION_ID); Long recordId = versionHistoryRequest.getNewData().getId(); String tableName = getTableName(versionHistoryRequest.getNewData().getClass()); - versionHistoryRequest.setRecordId(recordId); - versionHistoryRequest.setUserActionId(userActionId); - versionHistoryRequest.setTableName(tableName); - logVersionHistory(versionHistoryRequest); + logVersionHistory(versionHistoryRequest, recordId, userActionId, tableName); } catch (Exception e) { log.error("Error adding version history: {}", e.getMessage(), e); } diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/CallApiController.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/CallApiController.java index 40b3679f..5bd63df2 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/CallApiController.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/CallApiController.java @@ -42,25 +42,20 @@ public class CallApiController implements CallApi { @Autowired private LoggingUtil loggingUtil; - @Autowired - private UserActionsRepository userActionsRepository; - @Override - @Transactional(rollbackFor = Exception.class) public ResponseEntity> createCallStep1(HttpServletRequest request, CreateCallRequestStep1 createCallRequest) { - - UserActionRequest userActionRequest = new UserActionRequest(); - userActionRequest.setRequest(request); - userActionRequest.setActionType(UserActionLogsEnum.INSERT); - userActionRequest.setActionContext(UserActionContextEnum.CREATE_CALL.getValue()); - loggingUtil.logUserAction(userActionRequest); + + /** This code is responsible for creating user action logs for the "Create Call" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.INSERT) + .actionContext(UserActionContextEnum.CREATE_CALL).actionContext(UserActionContextEnum.CREATE_CALL) + .build()); + CallResponse createCallResponseBean = callService.createCallStep1(request, createCallRequest); return ResponseEntity.status(HttpStatus.CREATED) .body(new Response<>(createCallResponseBean, Status.SUCCESS, Translator.toLocale(GepafinConstant.CALL_CREATED_SUCCESSFULLY_MSG))); } @Override - @Transactional(rollbackFor=Exception.class) public ResponseEntity> createCallStep2(HttpServletRequest request, Long callId, CreateCallRequestStep2 createCallRequest) { CallResponse createCallResponseBean = callService.createCallStep2(request, callId, createCallRequest); return ResponseEntity.status(HttpStatus.CREATED) @@ -68,7 +63,6 @@ public class CallApiController implements CallApi { } @Override - @Transactional(rollbackFor=Exception.class) public ResponseEntity> updateCallStep1(HttpServletRequest request, Long callId, UpdateCallRequestStep1 updateCallRequest) { CallResponse createCallResponseBean = callService.updateCallStep1(request, callId, updateCallRequest); return ResponseEntity.status(HttpStatus.CREATED) @@ -83,7 +77,6 @@ public class CallApiController implements CallApi { } @Override - @Transactional(readOnly = true) public ResponseEntity>> getAllCalls(HttpServletRequest request,Long companyId) { List calls = callService.getAllCalls(request,companyId); From 18e970219d815b353add47ba1c7427437f34b96f Mon Sep 17 00:00:00 2001 From: piyushkag Date: Wed, 20 Nov 2024 15:58:31 +0530 Subject: [PATCH 03/43] Updated Code for logging. --- .../gepafin/tendermanagement/util/Utils.java | 42 +++++++++++++------ .../web/rest/api/impl/CallApiController.java | 4 +- 2 files changed, 30 insertions(+), 16 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/util/Utils.java b/src/main/java/net/gepafin/tendermanagement/util/Utils.java index 76f4fac6..efba6f31 100644 --- a/src/main/java/net/gepafin/tendermanagement/util/Utils.java +++ b/src/main/java/net/gepafin/tendermanagement/util/Utils.java @@ -15,9 +15,14 @@ import java.util.regex.Pattern; import java.util.stream.Collectors; import com.fasterxml.jackson.annotation.JsonAutoDetect; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.PropertyAccessor; +import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.SerializationFeature; +import com.fasterxml.jackson.databind.node.ObjectNode; +import jakarta.persistence.ManyToMany; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.OneToMany; +import jakarta.persistence.OneToOne; import jakarta.servlet.http.HttpServletRequest; import net.gepafin.tendermanagement.constants.GepafinConstant; import org.apache.commons.collections4.MapUtils; @@ -517,19 +522,30 @@ public class Utils { public static String convertEntityToJsonForLogging(Object entity) { - if(entity == null){ + if (entity == null) { return null; } - try { - return mapper.writeValueAsString(entity); - } catch (JsonProcessingException e) { - e.printStackTrace(); - return null; - } - } - @JsonIgnoreProperties({ "childEntities", "relatedData", "otherRelations" }) - private abstract static class IgnoreChildEntities { + try { + mapper.registerModule(new JavaTimeModule()); + mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); + mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY); + + JsonNode entityNode = mapper.valueToTree(entity); + ObjectNode objectNode = (ObjectNode) entityNode; + + Field[] fields = entity.getClass().getDeclaredFields(); + for (Field field : fields) { + if (field.getType().isAnnotationPresent(ManyToOne.class) || field.getType().isAnnotationPresent(OneToMany.class) || field.getType() + .isAnnotationPresent(OneToOne.class) || field.getType().isAnnotationPresent(ManyToMany.class)) { + objectNode.remove(field.getName()); + } + } + return mapper.writeValueAsString(objectNode); + } catch (JsonProcessingException e) { + log.error("Failed to parse entity in json {}", e.getMessage()); + return null; + } } public static T getClonedEntityForData(T entity) { @@ -542,8 +558,8 @@ public class Utils { @SuppressWarnings("unchecked") T clonedEntity = (T) mapper.readValue(json, entity.getClass()); return clonedEntity; } catch (Exception e) { - e.printStackTrace(); - throw new RuntimeException("Failed to clone entity", e); + log.error("Failed to clone entity {}", e.getMessage()); + return null; } } } diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/CallApiController.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/CallApiController.java index 5bd63df2..28088304 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/CallApiController.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/CallApiController.java @@ -46,9 +46,7 @@ public class CallApiController implements CallApi { public ResponseEntity> createCallStep1(HttpServletRequest request, CreateCallRequestStep1 createCallRequest) { /** This code is responsible for creating user action logs for the "Create Call" operation. **/ - loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.INSERT) - .actionContext(UserActionContextEnum.CREATE_CALL).actionContext(UserActionContextEnum.CREATE_CALL) - .build()); + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.INSERT).actionContext(UserActionContextEnum.CREATE_CALL).build()); CallResponse createCallResponseBean = callService.createCallStep1(request, createCallRequest); return ResponseEntity.status(HttpStatus.CREATED) From f1eec85112cd970ce29ac233c60400717a07ef98 Mon Sep 17 00:00:00 2001 From: piyushkag Date: Wed, 20 Nov 2024 19:05:07 +0530 Subject: [PATCH 04/43] Updated code for removing child entity from parent. --- src/main/java/net/gepafin/tendermanagement/util/Utils.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/util/Utils.java b/src/main/java/net/gepafin/tendermanagement/util/Utils.java index efba6f31..b414efb9 100644 --- a/src/main/java/net/gepafin/tendermanagement/util/Utils.java +++ b/src/main/java/net/gepafin/tendermanagement/util/Utils.java @@ -536,8 +536,8 @@ public class Utils { Field[] fields = entity.getClass().getDeclaredFields(); for (Field field : fields) { - if (field.getType().isAnnotationPresent(ManyToOne.class) || field.getType().isAnnotationPresent(OneToMany.class) || field.getType() - .isAnnotationPresent(OneToOne.class) || field.getType().isAnnotationPresent(ManyToMany.class)) { + if (field.isAnnotationPresent(ManyToOne.class) || field.isAnnotationPresent(OneToMany.class) || field + .isAnnotationPresent(OneToOne.class) || field.isAnnotationPresent(ManyToMany.class)) { objectNode.remove(field.getName()); } } From c0906c9e7d181a7bd6d253ea7ed0e1225b553b8a Mon Sep 17 00:00:00 2001 From: rajesh Date: Wed, 20 Nov 2024 19:16:28 +0530 Subject: [PATCH 05/43] added user action log for call apis --- .../gepafin/tendermanagement/dao/CallDao.java | 60 +++++++++++++++---- .../enums/UserActionContextEnum.java | 7 ++- .../tendermanagement/util/LoggingUtil.java | 5 -- .../web/rest/api/impl/CallApiController.java | 45 ++++++++++++-- 4 files changed, 94 insertions(+), 23 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java b/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java index 3a2dd9e4..4d2e341c 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java @@ -211,8 +211,13 @@ public class CallDao { } private void softDeleteEvaluationCriteria(EvaluationCriteriaEntity evaluationCriteriaEntity) { + EvaluationCriteriaEntity oldEvaluationCriteriaEntity = Utils.getClonedEntityForData(evaluationCriteriaEntity); evaluationCriteriaEntity.setIsDeleted(true); evaluationCriteriaRepository.save(evaluationCriteriaEntity); + + /** This code is responsible for adding a version history log for the "soft delete evaluation criteria" operation **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.SOFT_DELETE).oldData(oldEvaluationCriteriaEntity).newData(evaluationCriteriaEntity).build()); + List list = criteriaFormFieldRepository .findByEvaluationCriteriaIdAndIsDeletedFalse(evaluationCriteriaEntity.getId()) .stream() @@ -269,13 +274,18 @@ public class CallDao { .forEach(this::softDeleteDocument); List documentEntities = documentReqList.stream() .map(req -> convertToDocumentEntity(req, sourceId)).collect(Collectors.toList()); - documentRepository.saveAll(documentEntities); +// documentRepository.saveAll(documentEntities); return documentEntities; } private void softDeleteDocument(DocumentEntity documentEntity) { + DocumentEntity oldDocumentEntity = Utils.getClonedEntityForData(documentEntity); documentEntity.setIsDeleted(true); - documentRepository.save(documentEntity); + documentEntity = documentRepository.save(documentEntity); + + /** This code is responsible for adding a version history log for the "soft delete for document" operation **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.SOFT_DELETE).oldData(oldDocumentEntity).newData(documentEntity).build()); + } @@ -476,8 +486,14 @@ public class CallDao { public CallResponse createCallStep2(CallEntity callEntity, CreateCallRequestStep2 createCallRequest, UserEntity user) { // validateUpdate(callEntity); - setIfUpdated(callEntity::getThreshold, callEntity::setThreshold, createCallRequest.getThreshold()); - callRepository.save(callEntity); + if(createCallRequest.getThreshold() != null && Boolean.FALSE.equals(createCallRequest.getThreshold().equals(callEntity.getThreshold()))) { + CallEntity oldCallEntity = Utils.getClonedEntityForData(callEntity); + setIfUpdated(callEntity::getThreshold, callEntity::setThreshold, createCallRequest.getThreshold()); + callEntity = callRepository.save(callEntity); + + /** This code is responsible for adding a version history log for the "update call step 2" operation **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldCallEntity).newData(callEntity).build()); + } convertToEvaluationCriteriaEntities(createCallRequest.getCriteria(), callEntity, LookUpDataTypeEnum.EVALUATION_CRITERIA); convertToDocumentEntities(createCallRequest.getDocs(), callEntity.getId(), DocumentTypeEnum.DOCUMENT); @@ -486,14 +502,6 @@ public class CallDao { updateLookUpData(callEntity, createCallRequest.getCheckList(), LookUpDataTypeEnum.CHECKLIST); -// List faqEntities = faqRepository.findByCallIdAndIsDeletedFalse(callEntity.getId()); -// List amiedTo = callTargetAudienceChecklistRepository -// .findByCallIdAndLookupDataTypeAndIsDeletedFalse(callEntity.getId(), LookUpDataTypeEnum.AIMED_TO.getValue()).stream() -// .map(this::convertToLookUpDataResponseBean).toList(); -// createCallResponseBean = assembleCreateCallResponseBean(callEntity, evaluationCriteriaEntities, -// documentEntities, faqEntities, imageEntities); -// createCallResponseBean.setAimedTo(amiedTo); -// createCallResponseBean.setCheckList(checkList); CallResponse createCallResponseBean = getCallResponseBean(callEntity); createCallResponseBean.setCurrentStep(GepafinConstant.STEP_2); return createCallResponseBean; @@ -535,6 +543,7 @@ public class CallDao { } public CallResponse updateCallStep1(CallEntity callEntity, UpdateCallRequestStep1 updateCallRequest, UserEntity userEntity) { + CallEntity oldCallEntity = Utils.getClonedEntityForData(callEntity); isValidDateRange(updateCallRequest, callEntity); setIfUpdated(callEntity::getName, callEntity::setName, updateCallRequest.getName()); setIfUpdated(callEntity::getDescriptionShort, callEntity::setDescriptionShort, @@ -570,6 +579,11 @@ public class CallDao { setIfUpdated(callEntity::getStartTime, callEntity::setStartTime, DateTimeUtil.parseTime(updateCallRequest.getStartTime())); setIfUpdated(callEntity::getEndTime, callEntity::setEndTime, DateTimeUtil.parseTime(updateCallRequest.getEndTime())); setIfUpdated(callEntity::getConfidi, callEntity::setConfidi, updateCallRequest.getConfidi()); + callEntity = callRepository.save(callEntity); + + /** This code is responsible for adding a version history log for the "update call step 1" operation **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldCallEntity).newData(callEntity).build()); + updateLookUpData(callEntity, updateCallRequest.getAimedTo(), LookUpDataTypeEnum.AIMED_TO); updateFaq(updateCallRequest.getFaq(), callEntity, userEntity, LookUpDataTypeEnum.FAQ); CallResponse createCallResponseBean = getCallResponseBean(callEntity); @@ -578,8 +592,14 @@ public class CallDao { } private void softDeleteFaq(FaqEntity faqEntity) { + + FaqEntity oldFaqEntity = Utils.getClonedEntityForData(faqEntity); + faqEntity.setIsDeleted(true); faqRepository.save(faqEntity); + + /** This code is responsible for adding a version history log for the "soft delete faq" operation **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.SOFT_DELETE).oldData(oldFaqEntity).newData(faqEntity).build()); } private void updateLookUpData(CallEntity callEntity, List lookupDataReqList, LookUpDataTypeEnum type) { @@ -628,8 +648,12 @@ public class CallDao { private void softDeleteCallTargetAudienceChecklist( CallTargetAudienceChecklistEntity callTargetAudienceChecklistEntity) { + CallTargetAudienceChecklistEntity oldCallTargetAudienceChecklistEntity = Utils.getClonedEntityForData(callTargetAudienceChecklistEntity); callTargetAudienceChecklistEntity.setIsDeleted(true); callTargetAudienceChecklistRepository.save(callTargetAudienceChecklistEntity); + + /** This code is responsible for adding a version history log for the "soft delete for aimedTo or Checklist" operation **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.SOFT_DELETE).oldData(oldCallTargetAudienceChecklistEntity).newData(callTargetAudienceChecklistEntity).build()); } public CallDetailsResponseBean convertToCallDetailsResponseBean(CallEntity callEntity) { @@ -741,13 +765,18 @@ public class CallDao { public CallResponse validateCallData(CallEntity callEntity) { + CallEntity oldCallEntity = Utils.getClonedEntityForData(callEntity); validateUpdate(callEntity); CallResponse callResponseBean = getCallResponseBean(callEntity); FlowResponseBean flowResponseBean = flowDao.getFlowByCallId(callEntity.getId()); List formResponseBean = formDao.getFormsByCallId(callEntity); CallValidatorServiceImpl.validateResponse(callResponseBean,flowResponseBean,formResponseBean); callEntity.setStatus(CallStatusEnum.READY_TO_PUBLISH.getValue()); - callRepository.save(callEntity); + callEntity = callRepository.save(callEntity); + + /** This code is responsible for adding a version history log for the "validate call" operation **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldCallEntity).newData(callEntity).build()); + callResponseBean.setCurrentStep(GepafinConstant.VALIDATE_REQUEST); callResponseBean.setStatus(CallStatusEnum.valueOf(callEntity.getStatus())); return callResponseBean; @@ -761,10 +790,15 @@ public class CallDao { // } public CallResponse updateCallStatus(CallEntity callEntity, CallStatusEnum statusReq) { + CallEntity oldCallEntity = Utils.getClonedEntityForData(callEntity); CallStatusEnum currentStatus = CallStatusEnum.valueOf(callEntity.getStatus()); validateStatusChange(currentStatus, statusReq); callEntity.setStatus(statusReq.getValue()); callEntity = callRepository.save(callEntity); + + /** This code is responsible for adding a version history log for the "update call status" operation **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldCallEntity).newData(callEntity).build()); + return convertToCallResponseBean(callEntity); } diff --git a/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java index be56c433..41c76a23 100644 --- a/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java +++ b/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java @@ -3,7 +3,12 @@ package net.gepafin.tendermanagement.enums; import com.fasterxml.jackson.annotation.JsonValue; public enum UserActionContextEnum { - CREATE_CALL("CREATE_CALL"),; + CREATE_CALL_STEP_1("CREATE_CALL_STEP_1"), + UPDATE_CALL_STEP_1("UPDATE_CALL_STEP_1"), + UPDATE_CALL_STEP_2("UPDATE_CALL_STEP_2"), + VALIDATE_CALL("VALIDATE_CALL"), + UPDATE_CALL_STATUS("UPDATE_CALL_STATUS"), + GET_CALL("GET_CALL"); private final String value; diff --git a/src/main/java/net/gepafin/tendermanagement/util/LoggingUtil.java b/src/main/java/net/gepafin/tendermanagement/util/LoggingUtil.java index ecab52e4..fcddb98a 100644 --- a/src/main/java/net/gepafin/tendermanagement/util/LoggingUtil.java +++ b/src/main/java/net/gepafin/tendermanagement/util/LoggingUtil.java @@ -1,10 +1,7 @@ package net.gepafin.tendermanagement.util; -import com.fasterxml.jackson.databind.ObjectMapper; import io.jsonwebtoken.Claims; import jakarta.persistence.Table; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; import lombok.extern.slf4j.Slf4j; import net.gepafin.tendermanagement.config.CachedBodyHttpServletRequest; import net.gepafin.tendermanagement.config.jwt.TokenProvider; @@ -14,13 +11,11 @@ import net.gepafin.tendermanagement.entities.UserEntity; import net.gepafin.tendermanagement.entities.VersionHistoryEntity; import net.gepafin.tendermanagement.model.request.UserActionRequest; import net.gepafin.tendermanagement.model.request.VersionHistoryRequest; -import net.gepafin.tendermanagement.model.util.LogResponse; import net.gepafin.tendermanagement.repositories.UserActionsRepository; import net.gepafin.tendermanagement.repositories.VersionHistoryRepository; import net.gepafin.tendermanagement.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import org.springframework.transaction.annotation.Transactional; import org.springframework.web.context.annotation.RequestScope; @Slf4j diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/CallApiController.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/CallApiController.java index 28088304..4171ef8b 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/CallApiController.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/CallApiController.java @@ -2,12 +2,10 @@ package net.gepafin.tendermanagement.web.rest.api.impl; import java.util.List; -import lombok.extern.slf4j.Slf4j; import net.gepafin.tendermanagement.enums.CallStatusEnum; import net.gepafin.tendermanagement.enums.UserActionContextEnum; import net.gepafin.tendermanagement.enums.UserActionLogsEnum; import net.gepafin.tendermanagement.model.request.UserActionRequest; -import net.gepafin.tendermanagement.repositories.UserActionsRepository; import net.gepafin.tendermanagement.util.LoggingUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpHeaders; @@ -45,8 +43,9 @@ public class CallApiController implements CallApi { @Override public ResponseEntity> createCallStep1(HttpServletRequest request, CreateCallRequestStep1 createCallRequest) { - /** This code is responsible for creating user action logs for the "Create Call" operation. **/ - loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.INSERT).actionContext(UserActionContextEnum.CREATE_CALL).build()); + /** This code is responsible for creating user action logs for the "Create Call Step 1" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.INSERT) + .actionContext(UserActionContextEnum.CREATE_CALL_STEP_1).build()); CallResponse createCallResponseBean = callService.createCallStep1(request, createCallRequest); return ResponseEntity.status(HttpStatus.CREATED) @@ -55,6 +54,11 @@ public class CallApiController implements CallApi { @Override public ResponseEntity> createCallStep2(HttpServletRequest request, Long callId, CreateCallRequestStep2 createCallRequest) { + + /** This code is responsible for creating user action logs for the "Create or update Call step 2" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.UPDATE) + .actionContext(UserActionContextEnum.UPDATE_CALL_STEP_2).build()); + CallResponse createCallResponseBean = callService.createCallStep2(request, callId, createCallRequest); return ResponseEntity.status(HttpStatus.CREATED) .body(new Response<>(createCallResponseBean, Status.SUCCESS, Translator.toLocale(GepafinConstant.CALL_CREATED_SUCCESSFULLY_MSG))); @@ -62,6 +66,11 @@ public class CallApiController implements CallApi { @Override public ResponseEntity> updateCallStep1(HttpServletRequest request, Long callId, UpdateCallRequestStep1 updateCallRequest) { + + /** This code is responsible for creating user action logs for the "update Call step 1" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.UPDATE) + .actionContext(UserActionContextEnum.UPDATE_CALL_STEP_1).build()); + CallResponse createCallResponseBean = callService.updateCallStep1(request, callId, updateCallRequest); return ResponseEntity.status(HttpStatus.CREATED) .body(new Response<>(createCallResponseBean, Status.SUCCESS, Translator.toLocale(GepafinConstant.CALL_UPDATE_SUCCESSFULLY_MSG))); @@ -69,6 +78,11 @@ public class CallApiController implements CallApi { @Override @Transactional(readOnly = true) public ResponseEntity> getCallById(HttpServletRequest request, Long callId,Long companyId) { + + /** This code is responsible for creating user action logs for the "get Call by id" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.VIEW) + .actionContext(UserActionContextEnum.GET_CALL).build()); + CallResponse createCallResponseBean = callService.getCallById(request, callId,companyId); return ResponseEntity.status(HttpStatus.OK) .body(new Response<>(createCallResponseBean, Status.SUCCESS, Translator.toLocale(GepafinConstant.CALL_FETCH_SUCCESS_MSG))); @@ -76,6 +90,12 @@ public class CallApiController implements CallApi { @Override public ResponseEntity>> getAllCalls(HttpServletRequest request,Long companyId) { + + + /** This code is responsible for creating user action logs for the "get Calls" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.VIEW) + .actionContext(UserActionContextEnum.GET_CALL).build()); + List calls = callService.getAllCalls(request,companyId); return ResponseEntity.status(HttpStatus.OK) @@ -84,6 +104,13 @@ public class CallApiController implements CallApi { } @Override public ResponseEntity> validateCallData(HttpServletRequest request, Long callId) { + + + /** This code is responsible for creating user action logs for the "validate Call" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.UPDATE) + .actionContext(UserActionContextEnum.VALIDATE_CALL).build()); + + CallResponse call = callService.validateCallData(request, callId); return ResponseEntity.status(HttpStatus.OK) @@ -91,11 +118,21 @@ public class CallApiController implements CallApi { } @Override public ResponseEntity> updateCallStatus(HttpServletRequest request, Long callId, CallStatusEnum status) { + + /** This code is responsible for creating user action logs for the "update Call status" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.UPDATE) + .actionContext(UserActionContextEnum.UPDATE_CALL_STATUS).build()); + CallResponse updateCall = callService.updateCallStatus(request, callId, status); return ResponseEntity.ok(new Response<>(updateCall, Status.SUCCESS, Translator.toLocale(GepafinConstant.UPDATE_CALL_STATUS_SUCCESS_MSG))); } @Override public ResponseEntity downloadCallDocumentsAsZip(HttpServletRequest request, Long callId) { + + /** This code is responsible for creating user action logs for the "download Call documents " operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.VIEW) + .actionContext(UserActionContextEnum.GET_CALL).build()); + byte[] zipFile = callService.downloadCallDocumentsAsZip(request, callId); HttpHeaders headers = new HttpHeaders(); From 531738f82f4c3723f41d04f49ee1958045dab385 Mon Sep 17 00:00:00 2001 From: rajesh Date: Thu, 21 Nov 2024 13:04:57 +0530 Subject: [PATCH 06/43] updated code for call user action --- .../gepafin/tendermanagement/dao/CallDao.java | 21 ++++++++++++++----- .../enums/UserActionContextEnum.java | 11 ++++++++-- .../enums/UserActionLogsEnum.java | 2 +- .../tendermanagement/util/LoggingUtil.java | 7 ++++++- .../web/rest/api/impl/CallApiController.java | 6 +++--- 5 files changed, 35 insertions(+), 12 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java b/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java index 4d2e341c..b6ef828b 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java @@ -27,6 +27,7 @@ import net.gepafin.tendermanagement.util.Validator; import org.h2.util.IOUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; import net.gepafin.tendermanagement.config.Translator; @@ -219,11 +220,20 @@ public class CallDao { loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.SOFT_DELETE).oldData(oldEvaluationCriteriaEntity).newData(evaluationCriteriaEntity).build()); List list = criteriaFormFieldRepository - .findByEvaluationCriteriaIdAndIsDeletedFalse(evaluationCriteriaEntity.getId()) - .stream() - .peek(data -> data.setIsDeleted(Boolean.TRUE)) - .toList(); - criteriaFormFieldRepository.saveAll(list); + .findByEvaluationCriteriaIdAndIsDeletedFalse(evaluationCriteriaEntity.getId()); + + if(Boolean.FALSE.equals(CollectionUtils.isEmpty(list))) { + + list.stream().peek(data->{ + CriteriaFormFieldEntity oldCriteriaFormFieldEntity = Utils.getClonedEntityForData(data); + data.setIsDeleted(Boolean.TRUE); + + /** This code is responsible for adding a version history log for the "soft delete criteria form field" operation **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.SOFT_DELETE).oldData(oldCriteriaFormFieldEntity).newData(data).build()); + }); + criteriaFormFieldRepository.saveAll(list); + + } } private EvaluationCriteriaEntity convertToEvaluationCriteriaEntity(EvaluationCriteriaReq criteriaReq, @@ -630,6 +640,7 @@ public class CallDao { if (Boolean.FALSE.equals(checklistEntity.getLookupData().getId().equals(lookupDataEntity.getId()))) { checklistEntity.setLookupData(lookupDataEntity); } + oldChecklistEntity = Utils.getClonedEntityForData(checklistEntity); actionType = VersionActionTypeEnum.UPDATE; } else { checklistEntity = new CallTargetAudienceChecklistEntity(); diff --git a/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java index 41c76a23..4b1f699c 100644 --- a/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java +++ b/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java @@ -3,12 +3,19 @@ package net.gepafin.tendermanagement.enums; import com.fasterxml.jackson.annotation.JsonValue; public enum UserActionContextEnum { + + /** call action context **/ CREATE_CALL_STEP_1("CREATE_CALL_STEP_1"), UPDATE_CALL_STEP_1("UPDATE_CALL_STEP_1"), - UPDATE_CALL_STEP_2("UPDATE_CALL_STEP_2"), + CREATE_UPDATE_CALL_STEP_2("CREATE_UPDATE_CALL_STEP_2"), VALIDATE_CALL("VALIDATE_CALL"), UPDATE_CALL_STATUS("UPDATE_CALL_STATUS"), - GET_CALL("GET_CALL"); + GET_CALL("GET_CALL"), + DOWNLOAD_CALL_DOCUMENT("DOWNLOAD_CALL_DOCUMENT"), + + + /** user action context **/ + CREATE_USER("CREATE_USER"); private final String value; diff --git a/src/main/java/net/gepafin/tendermanagement/enums/UserActionLogsEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/UserActionLogsEnum.java index 65f2243d..7e7aebe1 100644 --- a/src/main/java/net/gepafin/tendermanagement/enums/UserActionLogsEnum.java +++ b/src/main/java/net/gepafin/tendermanagement/enums/UserActionLogsEnum.java @@ -3,7 +3,7 @@ package net.gepafin.tendermanagement.enums; import com.fasterxml.jackson.annotation.JsonValue; public enum UserActionLogsEnum { - LOGIN("LOGIN"), LOGOUT("LOGOUT"), UPDATE("UPDATE"), DELETE("DELETE"), VIEW("VIEW"), INSERT("INSERT"); + LOGIN("LOGIN"), LOGOUT("LOGOUT"), UPDATE("UPDATE"), DELETE("DELETE"), VIEW("VIEW"), INSERT("INSERT"), DOWNLOAD("DOWNLOAD"), UPLOAD("UPLOAD"); private final String value; diff --git a/src/main/java/net/gepafin/tendermanagement/util/LoggingUtil.java b/src/main/java/net/gepafin/tendermanagement/util/LoggingUtil.java index fcddb98a..67c8e75b 100644 --- a/src/main/java/net/gepafin/tendermanagement/util/LoggingUtil.java +++ b/src/main/java/net/gepafin/tendermanagement/util/LoggingUtil.java @@ -131,7 +131,12 @@ public class LoggingUtil { public void addVersionHistory(VersionHistoryRequest versionHistoryRequest) { try { Long userActionId = (Long) versionHistoryRequest.getRequest().getAttribute(GepafinConstant.USER_ACTION_ID); - Long recordId = versionHistoryRequest.getNewData().getId(); + Long recordId = null; + if(versionHistoryRequest.getNewData() != null) { + recordId = versionHistoryRequest.getNewData().getId(); + } else if(versionHistoryRequest.getOldData() != null){ + recordId = versionHistoryRequest.getOldData().getId(); + } String tableName = getTableName(versionHistoryRequest.getNewData().getClass()); logVersionHistory(versionHistoryRequest, recordId, userActionId, tableName); } catch (Exception e) { diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/CallApiController.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/CallApiController.java index 4171ef8b..e4a8669d 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/CallApiController.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/CallApiController.java @@ -57,7 +57,7 @@ public class CallApiController implements CallApi { /** This code is responsible for creating user action logs for the "Create or update Call step 2" operation. **/ loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.UPDATE) - .actionContext(UserActionContextEnum.UPDATE_CALL_STEP_2).build()); + .actionContext(UserActionContextEnum.CREATE_UPDATE_CALL_STEP_2).build()); CallResponse createCallResponseBean = callService.createCallStep2(request, callId, createCallRequest); return ResponseEntity.status(HttpStatus.CREATED) @@ -130,8 +130,8 @@ public class CallApiController implements CallApi { public ResponseEntity downloadCallDocumentsAsZip(HttpServletRequest request, Long callId) { /** This code is responsible for creating user action logs for the "download Call documents " operation. **/ - loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.VIEW) - .actionContext(UserActionContextEnum.GET_CALL).build()); + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.DOWNLOAD) + .actionContext(UserActionContextEnum.DOWNLOAD_CALL_DOCUMENT).build()); byte[] zipFile = callService.downloadCallDocumentsAsZip(request, callId); From dd148c0ebfb66d0ff00f2c469bd130f6e8f7af89 Mon Sep 17 00:00:00 2001 From: piyushkag Date: Fri, 22 Nov 2024 09:05:21 +0530 Subject: [PATCH 07/43] Added action logs for user api's. --- .../constants/GepafinConstant.java | 2 +- .../tendermanagement/dao/LoginAttemptDao.java | 30 +++- .../gepafin/tendermanagement/dao/UserDao.java | 56 ++++-- .../entities/LoginAttemptEntity.java | 13 +- .../entities/UserActionEntity.java | 2 +- .../enums/UserActionContextEnum.java | 15 +- .../enums/UserActionLogsEnum.java | 9 +- .../enums/VersionActionTypeEnum.java | 5 +- .../model/request/UserActionRequest.java | 2 + .../repositories/UserActionsRepository.java | 1 + .../VersionHistoryRepository.java | 7 + .../service/impl/AuthenticationService.java | 26 ++- .../service/impl/UserServiceImpl.java | 6 + .../tendermanagement/util/LoggingUtil.java | 166 +++++++++++++++++- .../gepafin/tendermanagement/util/Utils.java | 12 +- .../web/rest/api/impl/CallApiController.java | 2 +- .../web/rest/api/impl/UserApiController.java | 116 +++++++++--- .../db/changelog/db.changelog-1.0.0.xml | 7 + 18 files changed, 404 insertions(+), 73 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java b/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java index d1f65647..516c15ed 100644 --- a/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java +++ b/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java @@ -156,7 +156,7 @@ public class GepafinConstant { public static final String IS_PIVA = "isPIVA"; public static final String FAILED_RETAIN_FIELD = "failed.retain.field"; public static final String USER_ALREADY_EXIST_MSG = "user.already.exist.msg"; - public static final String TOKEN_VALIDATE_SUCCESS_MSE = "token.validate.success"; + public static final String TOKEN_VALIDATE_SUCCESS_MSG = "token.validate.success"; public static final String INVALID_REQUEST = "invalid.request"; public static final String CODICE_FISCALE_EXISTS = "codice.fiscale.exists"; public static final String TOTAL_STEPS_NOT_BE_ZERO = "total.steps.not.zero"; diff --git a/src/main/java/net/gepafin/tendermanagement/dao/LoginAttemptDao.java b/src/main/java/net/gepafin/tendermanagement/dao/LoginAttemptDao.java index 9ff64040..a4629584 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/LoginAttemptDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/LoginAttemptDao.java @@ -1,12 +1,17 @@ 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.LoginAttemptEntity; import net.gepafin.tendermanagement.entities.UserEntity; +import net.gepafin.tendermanagement.enums.VersionActionTypeEnum; +import net.gepafin.tendermanagement.model.request.VersionHistoryRequest; import net.gepafin.tendermanagement.model.response.LoginAttemptPageableResponseBean; import net.gepafin.tendermanagement.repositories.LoginAttemptRepository; import net.gepafin.tendermanagement.util.DateTimeUtil; +import net.gepafin.tendermanagement.util.LoggingUtil; +import net.gepafin.tendermanagement.util.Utils; import net.gepafin.tendermanagement.web.rest.api.errors.Status; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; @@ -24,10 +29,29 @@ public class LoginAttemptDao { @Autowired LoginAttemptRepository loginAttemptRepository; - public void createLoginAttempt(LoginAttemptEntity loginAttemptEntity) { - loginAttemptEntity.setAttemptDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); + @Autowired + private LoggingUtil loggingUtil; - loginAttemptRepository.save(loginAttemptEntity); + @Autowired + private HttpServletRequest request; + + public LoginAttemptEntity createLoginAttempt(LoginAttemptEntity loginAttemptEntity) { + + VersionActionTypeEnum actionType; + LoginAttemptEntity oldLoginAttemptEntity = Utils.getClonedEntityForData(loginAttemptEntity); + loginAttemptEntity.setAttemptDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); + if(loginAttemptEntity.getId() != null ) { + actionType = VersionActionTypeEnum.UPDATE; + }else{ + actionType = VersionActionTypeEnum.INSERT; + oldLoginAttemptEntity = null; + } + loginAttemptEntity = loginAttemptRepository.save(loginAttemptEntity); + + /** This code is responsible for adding a version history log for "Create Login Attempt" operation. **/ + loggingUtil.addVersionHistoryWithoutToken(VersionHistoryRequest.builder().actionType(actionType).request(request).oldData(oldLoginAttemptEntity).newData(loginAttemptEntity).build()); + + return loginAttemptEntity; } public LoginAttemptPageableResponseBean> getLoginAttemptsList(UserEntity userEntity, Integer pageNo, Integer pageLimit) { diff --git a/src/main/java/net/gepafin/tendermanagement/dao/UserDao.java b/src/main/java/net/gepafin/tendermanagement/dao/UserDao.java index d5cda645..da5c6f07 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/UserDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/UserDao.java @@ -7,7 +7,10 @@ import net.gepafin.tendermanagement.config.Translator; import net.gepafin.tendermanagement.constants.GepafinConstant; import net.gepafin.tendermanagement.entities.*; import net.gepafin.tendermanagement.enums.RoleStatusEnum; +import net.gepafin.tendermanagement.enums.UserActionContextEnum; +import net.gepafin.tendermanagement.enums.UserActionLogsEnum; import net.gepafin.tendermanagement.enums.UserStatusEnum; +import net.gepafin.tendermanagement.enums.VersionActionTypeEnum; import net.gepafin.tendermanagement.model.request.*; import net.gepafin.tendermanagement.model.response.CompanyResponse; import net.gepafin.tendermanagement.model.response.RoleResponseBean; @@ -19,6 +22,7 @@ import net.gepafin.tendermanagement.repositories.UserRepository; import net.gepafin.tendermanagement.service.HubService; import net.gepafin.tendermanagement.service.RoleService; import net.gepafin.tendermanagement.service.impl.AuthenticationService; +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; @@ -80,28 +84,43 @@ public class UserDao { @Autowired private AuthenticationService authenticationService; - + @Autowired + private LoggingUtil loggingUtil; + + @Autowired + private HttpServletRequest request; + public JWTToken createUser(HttpServletRequest request, String tempToken, UserReq userReq) { - if(StringUtils.isEmpty(userReq.getHubUuid())) { - userReq.setHubUuid(defaultHubUuid); - } - HubEntity hub = hubService.getHubByUuid(userReq.getHubUuid()); - validateUserRequest(request, tempToken, userReq, hub); - validatePassword(userReq.getPassword(), userReq.getConfPassword(), tempToken); - RoleEntity roleEntity = getRoleEntity(userReq.getRoleId()); - BeneficiaryEntity beneficiary = createBeneficiary(roleEntity, userReq, hub); + + if (StringUtils.isEmpty(userReq.getHubUuid())) { + userReq.setHubUuid(defaultHubUuid); + } + HubEntity hub = hubService.getHubByUuid(userReq.getHubUuid()); + validateUserRequest(request, tempToken, userReq, hub); + validatePassword(userReq.getPassword(), userReq.getConfPassword(), tempToken); + RoleEntity roleEntity = getRoleEntity(userReq.getRoleId()); + BeneficiaryEntity beneficiary = createBeneficiary(roleEntity, userReq, hub); UserEntity userEntity = convertUserRequestToUserEntity(beneficiary, roleEntity, userReq, hub); log.info("User created with ID: {}", userEntity.getId()); - LoginReq loginReq=new LoginReq(); + LoginReq loginReq = new LoginReq(); loginReq.setEmail(userEntity.getEmail()); LoginAttemptEntity loginAttemptEntity = null; - if(userEntity!=null){ + if (userEntity != null) { loginAttemptEntity = authenticationService.prepareLoginAttemptEntity(loginReq, request); log.info("Authentication failed for email: {}", loginReq.getEmail()); loginAttemptEntity.setUserId(userEntity.getId()); - authenticationService.createSuccessLoginAttempt(loginAttemptEntity); + authenticationService.createSuccessLoginAttempt(loginAttemptEntity); } - return authService.getJWTTokenBean(userEntity, Boolean.TRUE, loginAttemptEntity.getId()); + + JWTToken token = authService.getJWTTokenBean(userEntity, Boolean.TRUE, loginAttemptEntity.getId()); + + /** This code is responsible for adding a version history log for the "Create beneficiary" operation. **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.INSERT).newData(beneficiary).build()); + + /** This code is responsible for adding a version history log for the "Create user" operation. **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.INSERT).newData(userEntity).build()); + + return token; } private BeneficiaryEntity createBeneficiary(RoleEntity roleEntity, UserReq userReq, HubEntity hub) { @@ -196,6 +215,7 @@ public class UserDao { public UserResponseBean updateUser(Long userId, UpdateUserReq userReq) { log.info("Updating user with ID: {}", userId); UserEntity userEntity=validateUser(userId); + UserEntity oldUserEntity = Utils.getClonedEntityForData(userEntity); log.info("Current user details: {}", userEntity); log.info("New user details: {}", userReq); String newStatus = userReq.getStatus() != null ? userReq.getStatus().getValue() : null; @@ -218,6 +238,10 @@ public class UserDao { } setIfUpdated(userEntity.getBeneficiary()::getEmailPec, userEntity.getBeneficiary()::setEmailPec, userReq.getEmailPec()); userEntity = userRepository.save(userEntity); + + /** This code is responsible for adding a version history log for the "Update user details" operation **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.INSERT).oldData(oldUserEntity).newData(userEntity).build()); + log.info("User updated with ID: {}", userEntity.getId()); return convertUserEntityToUserResponse(userEntity); } @@ -305,7 +329,11 @@ public class UserDao { public void deleteUser(Long id) { log.info("Deleting user with ID: {}", id); - validateUser(id); + UserEntity oldUserData = validateUser(id); + + /** This code is responsible for adding a version history log for the "Delete user" operation. **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.DELETE).oldData(oldUserData).build()); + userRepository.deleteById(id); log.info("User deleted with ID: {}", id); } diff --git a/src/main/java/net/gepafin/tendermanagement/entities/LoginAttemptEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/LoginAttemptEntity.java index 11fe1a99..bc3e445e 100644 --- a/src/main/java/net/gepafin/tendermanagement/entities/LoginAttemptEntity.java +++ b/src/main/java/net/gepafin/tendermanagement/entities/LoginAttemptEntity.java @@ -1,21 +1,14 @@ package net.gepafin.tendermanagement.entities; import jakarta.persistence.*; -import lombok.Getter; -import lombok.Setter; +import lombok.Data; import java.time.LocalDateTime; @Entity @Table(name = "LOGIN_ATTEMPT") -@Getter -@Setter -public class LoginAttemptEntity { - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - @Column(name = "ID", unique = true) - private Long id; +@Data +public class LoginAttemptEntity extends BaseEntity{ @Column(name = "USERNAME") private String username; diff --git a/src/main/java/net/gepafin/tendermanagement/entities/UserActionEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/UserActionEntity.java index 019f0317..488a6c71 100644 --- a/src/main/java/net/gepafin/tendermanagement/entities/UserActionEntity.java +++ b/src/main/java/net/gepafin/tendermanagement/entities/UserActionEntity.java @@ -38,6 +38,6 @@ public class UserActionEntity extends BaseEntity { private String actionContext; @Column(name = "RESPONSE") - private Object response; + private String response; } \ No newline at end of file diff --git a/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java index 4b1f699c..e2ffcd99 100644 --- a/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java +++ b/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java @@ -3,7 +3,7 @@ package net.gepafin.tendermanagement.enums; import com.fasterxml.jackson.annotation.JsonValue; public enum UserActionContextEnum { - + /** call action context **/ CREATE_CALL_STEP_1("CREATE_CALL_STEP_1"), UPDATE_CALL_STEP_1("UPDATE_CALL_STEP_1"), @@ -12,10 +12,17 @@ public enum UserActionContextEnum { UPDATE_CALL_STATUS("UPDATE_CALL_STATUS"), GET_CALL("GET_CALL"), DOWNLOAD_CALL_DOCUMENT("DOWNLOAD_CALL_DOCUMENT"), - - + /** user action context **/ - CREATE_USER("CREATE_USER"); + CREATE_USER("CREATE_USER"), + USER_LOGIN("USER_LOGIN"), + LOGOUT_USER("LOGOUT_USER"), + GET_USER("GET_USER"), + UPDATE_USER_DETAILS("UPDATE_USER_DETAILS"), + DELETE_USER("DELETE_USER"), + VALIDATE_NEW_USER_WITH_SPID_TOKEN("VALIDATE_NEW_USER_WITH_SPID_TOKEN"), + VALIDATE_EXISTING_USER_WITH_SPID_TOKEN("VALIDATE_EXISTING_USER_WITH_SPID_TOKEN"), + GET_VALID_USER_DETAILS("GET_VALID_USER_DETAILS"); private final String value; diff --git a/src/main/java/net/gepafin/tendermanagement/enums/UserActionLogsEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/UserActionLogsEnum.java index 7e7aebe1..f68f6ae9 100644 --- a/src/main/java/net/gepafin/tendermanagement/enums/UserActionLogsEnum.java +++ b/src/main/java/net/gepafin/tendermanagement/enums/UserActionLogsEnum.java @@ -3,7 +3,14 @@ package net.gepafin.tendermanagement.enums; import com.fasterxml.jackson.annotation.JsonValue; public enum UserActionLogsEnum { - LOGIN("LOGIN"), LOGOUT("LOGOUT"), UPDATE("UPDATE"), DELETE("DELETE"), VIEW("VIEW"), INSERT("INSERT"), DOWNLOAD("DOWNLOAD"), UPLOAD("UPLOAD"); + LOGIN("LOGIN"), + LOGOUT("LOGOUT"), + UPDATE("UPDATE"), + DELETE("DELETE"), + VIEW("VIEW"), + INSERT("INSERT"), + DOWNLOAD("DOWNLOAD"), + UPLOAD("UPLOAD"); private final String value; diff --git a/src/main/java/net/gepafin/tendermanagement/enums/VersionActionTypeEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/VersionActionTypeEnum.java index 27d2a55d..794999b0 100644 --- a/src/main/java/net/gepafin/tendermanagement/enums/VersionActionTypeEnum.java +++ b/src/main/java/net/gepafin/tendermanagement/enums/VersionActionTypeEnum.java @@ -3,7 +3,10 @@ package net.gepafin.tendermanagement.enums; import com.fasterxml.jackson.annotation.JsonValue; public enum VersionActionTypeEnum { - UPDATE("UPDATE"), DELETE("DELETE"), SOFT_DELETE("SOFT_DELETE"), INSERT("INSERT"); + UPDATE("UPDATE"), + DELETE("DELETE"), + SOFT_DELETE("SOFT_DELETE"), + INSERT("INSERT"); private final String value; diff --git a/src/main/java/net/gepafin/tendermanagement/model/request/UserActionRequest.java b/src/main/java/net/gepafin/tendermanagement/model/request/UserActionRequest.java index bdf6249b..bde1c273 100644 --- a/src/main/java/net/gepafin/tendermanagement/model/request/UserActionRequest.java +++ b/src/main/java/net/gepafin/tendermanagement/model/request/UserActionRequest.java @@ -1,6 +1,7 @@ package net.gepafin.tendermanagement.model.request; import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import lombok.Builder; import lombok.Data; import net.gepafin.tendermanagement.enums.UserActionContextEnum; @@ -12,4 +13,5 @@ public class UserActionRequest { private HttpServletRequest request; private UserActionLogsEnum actionType; private UserActionContextEnum actionContext; + private Object response; } diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/UserActionsRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/UserActionsRepository.java index ba651c6f..f0163c47 100644 --- a/src/main/java/net/gepafin/tendermanagement/repositories/UserActionsRepository.java +++ b/src/main/java/net/gepafin/tendermanagement/repositories/UserActionsRepository.java @@ -6,4 +6,5 @@ import org.springframework.stereotype.Repository; @Repository public interface UserActionsRepository extends JpaRepository { + UserActionEntity findUserActionById(Long id); } diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/VersionHistoryRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/VersionHistoryRepository.java index 059024ab..853bb945 100644 --- a/src/main/java/net/gepafin/tendermanagement/repositories/VersionHistoryRepository.java +++ b/src/main/java/net/gepafin/tendermanagement/repositories/VersionHistoryRepository.java @@ -4,6 +4,13 @@ import net.gepafin.tendermanagement.entities.VersionHistoryEntity; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; +import java.util.List; + @Repository public interface VersionHistoryRepository extends JpaRepository { + List findVersionHistoryById(Long id); + + List findVersionHistoryByUserActionIdAndUserIdNull(Long id); + + List findVersionHistoryByUserActionId(Long id); } diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/AuthenticationService.java b/src/main/java/net/gepafin/tendermanagement/service/impl/AuthenticationService.java index 30edb908..d4dab052 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/AuthenticationService.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/AuthenticationService.java @@ -15,16 +15,20 @@ import net.gepafin.tendermanagement.entities.UserEntity; import net.gepafin.tendermanagement.enums.LoginAttemptResultEnum; import net.gepafin.tendermanagement.enums.LoginAttemptTypeEnum; import net.gepafin.tendermanagement.enums.UserStatusEnum; +import net.gepafin.tendermanagement.enums.VersionActionTypeEnum; import net.gepafin.tendermanagement.model.request.LoginReq; +import net.gepafin.tendermanagement.model.request.VersionHistoryRequest; import net.gepafin.tendermanagement.model.response.CompanyResponse; import net.gepafin.tendermanagement.model.response.LoginResponse; import net.gepafin.tendermanagement.model.response.RoleResponseBean; import net.gepafin.tendermanagement.model.response.UserSamlResponse; import net.gepafin.tendermanagement.model.util.JWTToken; +import net.gepafin.tendermanagement.repositories.LoginAttemptRepository; import net.gepafin.tendermanagement.repositories.SamlResponseRepository; import net.gepafin.tendermanagement.repositories.UserRepository; import net.gepafin.tendermanagement.service.HubService; import net.gepafin.tendermanagement.util.DateTimeUtil; +import net.gepafin.tendermanagement.util.LoggingUtil; import net.gepafin.tendermanagement.util.Utils; import net.gepafin.tendermanagement.web.rest.api.errors.CustomValidationException; import net.gepafin.tendermanagement.web.rest.api.errors.ResourceNotFoundException; @@ -51,6 +55,7 @@ public class AuthenticationService { private final TokenProvider tokenProvider; private final AuthenticationManager authenticationManager; + @Autowired private CompanyDao companyDao; @@ -69,6 +74,15 @@ public class AuthenticationService { @Autowired private HubService hubService; + @Autowired + private HttpServletRequest request; + + @Autowired + private LoggingUtil loggingUtil; + + @Autowired + LoginAttemptRepository loginAttemptRepository; + @Autowired public AuthenticationService(TokenProvider tokenProvider, AuthenticationManager authenticationManager) { this.tokenProvider = tokenProvider; @@ -117,9 +131,9 @@ public class AuthenticationService { return loginAttemptEntity; } - public void createSuccessLoginAttempt(LoginAttemptEntity loginAttemptEntity) { + public LoginAttemptEntity createSuccessLoginAttempt(LoginAttemptEntity loginAttemptEntity) { loginAttemptEntity.setResult(LoginAttemptResultEnum.SUCCESS.getValue()); - loginAttemptDao.createLoginAttempt(loginAttemptEntity); + return loginAttemptDao.createLoginAttempt(loginAttemptEntity); } public void createFailedLoginAttempt(LoginAttemptEntity loginAttemptEntity, String errorMsg) { loginAttemptEntity.setResult(LoginAttemptResultEnum.FAILED.getValue()); @@ -127,9 +141,11 @@ public class AuthenticationService { loginAttemptDao.createLoginAttempt(loginAttemptEntity); } public JWTToken getJWTTokenBean(UserEntity user, Boolean rememberMe, Long loginAttemptId) { + UserEntity oldUserEntity = Utils.getClonedEntityForData(user); user.setLastLogin(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); user = userRepository.save(user); String token = tokenProvider.createToken(rememberMe, user, loginAttemptId); + log.info("JWT token generated for email: {}", user.getEmail()); RoleResponseBean roleResponseBean = roleDao.convertRoleEntityToRoleResponse(user.getRoleEntity()); @@ -137,6 +153,9 @@ public class AuthenticationService { JWTToken jwtToken = new JWTToken(token, loginResponse); + /** This code is responsible for adding a version history log for the "Create user Or Update user" operation. **/ + loggingUtil.addVersionHistoryWithoutToken(VersionHistoryRequest.builder().request(request).oldData(oldUserEntity).newData(user).actionType(VersionActionTypeEnum.UPDATE).build()); + log.info("Login successful for email: {}", user.getEmail()); return jwtToken; } @@ -215,7 +234,8 @@ public class AuthenticationService { loginReq.setEmail(userEntity.getEmail()); loginAttemptEntity = prepareLoginAttemptEntity(loginReq, request); loginAttemptEntity.setUserId(userEntity.getId()); - return getJWTTokenBean(userEntity, Boolean.TRUE, loginAttemptEntity.getId()); + LoginAttemptEntity loginAttempt = createSuccessLoginAttempt(loginAttemptEntity); + return getJWTTokenBean(userEntity, Boolean.TRUE, loginAttempt.getId()); } catch (Exception e) { log.info("Authentication login failed for email: {}",e.getMessage()); loginAttemptEntity.setUserId(userId); diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/UserServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/UserServiceImpl.java index d0b8a716..9f95b830 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/UserServiceImpl.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/UserServiceImpl.java @@ -4,6 +4,8 @@ import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import net.gepafin.tendermanagement.dao.UserDao; import net.gepafin.tendermanagement.entities.UserEntity; +import net.gepafin.tendermanagement.enums.UserActionContextEnum; +import net.gepafin.tendermanagement.enums.UserActionLogsEnum; import net.gepafin.tendermanagement.model.request.LoginReq; import net.gepafin.tendermanagement.model.request.UpdateUserReq; import net.gepafin.tendermanagement.model.request.UserReq; @@ -13,6 +15,7 @@ import net.gepafin.tendermanagement.model.response.UserSamlResponse; import net.gepafin.tendermanagement.model.response.UserResponseBean; import net.gepafin.tendermanagement.model.util.JWTToken; import net.gepafin.tendermanagement.service.UserService; +import net.gepafin.tendermanagement.util.LoggingUtil; import net.gepafin.tendermanagement.util.Validator; import org.springframework.beans.factory.annotation.Autowired; @@ -31,6 +34,9 @@ public class UserServiceImpl implements UserService { @Autowired private Validator validator; + @Autowired + private LoggingUtil loggingUtil; + @Override @Transactional(rollbackFor = Exception.class) public JWTToken createUser(HttpServletRequest request, String tempToken, UserReq userReq) { diff --git a/src/main/java/net/gepafin/tendermanagement/util/LoggingUtil.java b/src/main/java/net/gepafin/tendermanagement/util/LoggingUtil.java index 67c8e75b..ba7a750d 100644 --- a/src/main/java/net/gepafin/tendermanagement/util/LoggingUtil.java +++ b/src/main/java/net/gepafin/tendermanagement/util/LoggingUtil.java @@ -9,6 +9,7 @@ import net.gepafin.tendermanagement.constants.GepafinConstant; import net.gepafin.tendermanagement.entities.UserActionEntity; import net.gepafin.tendermanagement.entities.UserEntity; import net.gepafin.tendermanagement.entities.VersionHistoryEntity; +import net.gepafin.tendermanagement.enums.VersionActionTypeEnum; import net.gepafin.tendermanagement.model.request.UserActionRequest; import net.gepafin.tendermanagement.model.request.VersionHistoryRequest; import net.gepafin.tendermanagement.repositories.UserActionsRepository; @@ -18,6 +19,10 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.web.context.annotation.RequestScope; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + @Slf4j @Component @RequestScope @@ -33,13 +38,15 @@ public class LoggingUtil { private UserService userService; @Autowired - TokenProvider tokenProvider; + private TokenProvider tokenProvider; public UserActionEntity logUserAction(UserActionRequest userActionRequest) { UserActionEntity userAction = new UserActionEntity(); try { String token = tokenProvider.extractTokenFromRequest(userActionRequest.getRequest()); Claims claims = tokenProvider.getClaimsFromToken(token); + Map parameters = userActionRequest.getRequest().getParameterMap(); + parameters.forEach((key, value) -> log.info("Query Parameter: {} = {}", key, Arrays.toString(value))); Long userId = claims.get(GepafinConstant.USER_ID, Long.class); Long loginAttemptId = claims.get(GepafinConstant.LOGIN_ATTEMPT_ID, Long.class); UserEntity userEntity = userService.validateUser(userId); @@ -57,7 +64,8 @@ public class LoggingUtil { userAction.setLoginAttemptId(loginAttemptId); userAction.setIpAddress(IpAddressUtils.getClientIp(userActionRequest.getRequest())); userAction.setRequestBody(requestBody); - userAction.setResponse(null); + String response = Utils.convertEntityToJsonForLogging(userActionRequest.getResponse()); + userAction.setResponse(response); userActionsRepository.save(userAction); userActionRequest.getRequest().setAttribute(GepafinConstant.USER_ACTION_ID, userAction.getId()); } catch (Exception e) { @@ -116,6 +124,31 @@ public class LoggingUtil { } } + public void logVersionHistoryWithoutToken(VersionHistoryRequest versionHistoryRequest, Long recordId, Long userActionId, String tableName) { + try { + VersionHistoryEntity history = new VersionHistoryEntity(); + Long userId = null; + String token = tokenProvider.extractTokenFromRequest(versionHistoryRequest.getRequest()); + if(versionHistoryRequest.getRequest() != null && token != null) + { + Claims claims = tokenProvider.getClaimsFromToken(token); + userId = claims.get(GepafinConstant.USER_ID, Long.class); + } + String oldData = Utils.convertEntityToJsonForLogging(versionHistoryRequest.getOldData()); + String newData = Utils.convertEntityToJsonForLogging(versionHistoryRequest.getNewData()); + history.setUserActionId(userActionId); + history.setActionType(versionHistoryRequest.getActionType().getValue()); + history.setOldData(oldData); + history.setNewData(newData); + history.setRecordId(recordId); + history.setTableName(tableName); + history.setUserId(userId); + versionHistoryRepository.save(history); + } catch (Exception e) { + log.error("Error logging version history: {}", e.getMessage(), e); + } + } + public String getTableName(Class entityClass) { try { if (entityClass.isAnnotationPresent(Table.class)) { @@ -132,15 +165,138 @@ public class LoggingUtil { try { Long userActionId = (Long) versionHistoryRequest.getRequest().getAttribute(GepafinConstant.USER_ACTION_ID); Long recordId = null; + String tableName = null; if(versionHistoryRequest.getNewData() != null) { - recordId = versionHistoryRequest.getNewData().getId(); + recordId = versionHistoryRequest.getNewData().getId(); + tableName = getTableName(versionHistoryRequest.getNewData().getClass()); } else if(versionHistoryRequest.getOldData() != null){ - recordId = versionHistoryRequest.getOldData().getId(); + recordId = versionHistoryRequest.getOldData().getId(); } - String tableName = getTableName(versionHistoryRequest.getNewData().getClass()); logVersionHistory(versionHistoryRequest, recordId, userActionId, tableName); } catch (Exception e) { log.error("Error adding version history: {}", e.getMessage(), e); } } + + public void addVersionHistoryWithoutToken(VersionHistoryRequest versionHistoryRequest) { + try { + Long userActionId = (Long) versionHistoryRequest.getRequest().getAttribute(GepafinConstant.USER_ACTION_ID); + Long recordId = null; + String tableName = null; + if(versionHistoryRequest.getNewData() != null) { + recordId = versionHistoryRequest.getNewData().getId(); + tableName = getTableName(versionHistoryRequest.getNewData().getClass()); + } else if(versionHistoryRequest.getOldData() != null){ + recordId = versionHistoryRequest.getOldData().getId(); + tableName = getTableName(versionHistoryRequest.getOldData().getClass()); + } + versionHistoryRequest.setNewData(versionHistoryRequest.getNewData()); + versionHistoryRequest.setRequest(versionHistoryRequest.getRequest()); + logVersionHistoryWithoutToken(versionHistoryRequest, recordId, userActionId, tableName); + } catch (Exception e) { + log.error("Error adding version history: {}", e.getMessage(), e); + } + } + + public UserActionEntity logUserActionWithoutToken(UserActionRequest userActionRequest) { + UserActionEntity userAction = new UserActionEntity(); + try { + Long userId = null; + Long loginAttemptId = null; + Long hubId = null; + String token = tokenProvider.extractTokenFromRequest(userActionRequest.getRequest()); + Map parameters = userActionRequest.getRequest().getParameterMap(); + parameters.forEach((key, value) -> log.info("Query Parameter : {} = {}", key, Arrays.toString(value))); + if(userActionRequest.getRequest() != null && token != null) + { + Claims claims = tokenProvider.getClaimsFromToken(token); + userId = claims.get(GepafinConstant.USER_ID, Long.class); + loginAttemptId = claims.get(GepafinConstant.LOGIN_ATTEMPT_ID, Long.class); + UserEntity userEntity = userService.validateUser(userId); + hubId = userEntity.getHub().getId(); + } + + String requestBody = null; + if (userActionRequest.getRequest() instanceof CachedBodyHttpServletRequest cachedRequest) { + requestBody = cachedRequest.getCachedBodyAsString(); + } + userAction.setActionType(userActionRequest.getActionType().getValue()); + userAction.setUserId(userId); + userAction.setActionContext(userActionRequest.getActionContext().getValue()); + userAction.setMethodType(userActionRequest.getRequest().getMethod()); + userAction.setHubId(hubId); + userAction.setUrl(userActionRequest.getRequest().getRequestURI()); + userAction.setLoginAttemptId(loginAttemptId); + userAction.setIpAddress(IpAddressUtils.getClientIp(userActionRequest.getRequest())); + userAction.setRequestBody(requestBody); + String response = Utils.convertEntityToJsonForLogging(userActionRequest.getResponse()); + userAction.setResponse(response); + userActionsRepository.save(userAction); + userActionRequest.getRequest().setAttribute(GepafinConstant.USER_ACTION_ID, userAction.getId()); + } catch (Exception e) { + log.error("Error logging user action: {}", e.getMessage(), e); + } + return userAction; + } + public void updateUserActionWithTokenDetails(Long actionId, String token, Object response) { + + try { + UserActionEntity userAction = getUserActionLogById(actionId); + if (userAction != null && token != null) { + Claims claims = tokenProvider.getClaimsFromToken(token); + Long userId = claims.get(GepafinConstant.USER_ID, Long.class); + Long loginAttemptId = claims.get(GepafinConstant.LOGIN_ATTEMPT_ID, Long.class); + UserEntity userEntity = userService.validateUser(userId); + + userAction.setUserId(userId); + String responseData = Utils.convertEntityToJsonForLogging(response); + userAction.setResponse(responseData); + userAction.setLoginAttemptId(loginAttemptId); + userAction.setHubId(userEntity.getHub().getId()); + // Save updated entity + userActionsRepository.save(userAction); + log.info("User action log updated with token details: {}", userAction.getId()); + } + } catch (Exception e) { + log.error("Failed to update user action with token details: {}", e.getMessage(), e); + } + } + + public void updateVersionHistoriesWithTokenDetails(Long userActionId, String token) { + + try { + // Fetch version history entities for the given user action ID + List versionHistoryEntities = getVersionHistoryLogById(userActionId); + + if (versionHistoryEntities != null && !versionHistoryEntities.isEmpty() && token != null) { + // Extract claims from the token + Claims claims = tokenProvider.getClaimsFromToken(token); + Long userId = claims.get(GepafinConstant.USER_ID, Long.class); + + // Update each version history entity with the user ID + for (VersionHistoryEntity versionHistoryEntity : versionHistoryEntities) { + versionHistoryEntity.setUserId(userId); + } + + // Save all updated entities + versionHistoryRepository.saveAll(versionHistoryEntities); + + log.info("Version History logs updated with userId: {}", userId); + } else { + log.warn("No version history or token provided for userActionId: {}", userActionId); + } + } catch (Exception e) { + log.error("Failed to update version histories with token details: {}", e.getMessage(), e); + } + } + + + public UserActionEntity getUserActionLogById(Long id) { + + return userActionsRepository.findUserActionById(id); + } + public List getVersionHistoryLogById(Long id) { + + return versionHistoryRepository.findVersionHistoryByUserActionId(id); + } } diff --git a/src/main/java/net/gepafin/tendermanagement/util/Utils.java b/src/main/java/net/gepafin/tendermanagement/util/Utils.java index b414efb9..e71ac974 100644 --- a/src/main/java/net/gepafin/tendermanagement/util/Utils.java +++ b/src/main/java/net/gepafin/tendermanagement/util/Utils.java @@ -56,9 +56,8 @@ public class Utils { public static final Logger log = LoggerFactory.getLogger(Utils.class); - private static final ObjectMapper mapper = new ObjectMapper() - .registerModule(new JavaTimeModule()) - .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + private static final ObjectMapper mapper = new ObjectMapper().registerModule(new JavaTimeModule()).configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) + .registerModule(new JavaTimeModule()).disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS).setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY); public static U convertObject(T source, Class destinationClass) { try { @@ -527,17 +526,14 @@ public class Utils { } try { - mapper.registerModule(new JavaTimeModule()); - mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); - mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY); JsonNode entityNode = mapper.valueToTree(entity); ObjectNode objectNode = (ObjectNode) entityNode; Field[] fields = entity.getClass().getDeclaredFields(); for (Field field : fields) { - if (field.isAnnotationPresent(ManyToOne.class) || field.isAnnotationPresent(OneToMany.class) || field - .isAnnotationPresent(OneToOne.class) || field.isAnnotationPresent(ManyToMany.class)) { + if (field.isAnnotationPresent(ManyToOne.class) || field.isAnnotationPresent(OneToMany.class) || field.isAnnotationPresent( + OneToOne.class) || field.isAnnotationPresent(ManyToMany.class)) { objectNode.remove(field.getName()); } } diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/CallApiController.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/CallApiController.java index e4a8669d..13a01c5a 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/CallApiController.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/CallApiController.java @@ -76,7 +76,7 @@ public class CallApiController implements CallApi { .body(new Response<>(createCallResponseBean, Status.SUCCESS, Translator.toLocale(GepafinConstant.CALL_UPDATE_SUCCESSFULLY_MSG))); } @Override - @Transactional(readOnly = true) + @Transactional public ResponseEntity> getCallById(HttpServletRequest request, Long callId,Long companyId) { /** This code is responsible for creating user action logs for the "get Call by id" operation. **/ diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/UserApiController.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/UserApiController.java index 1a3040c1..0b170375 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/UserApiController.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/UserApiController.java @@ -4,7 +4,11 @@ import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import jakarta.validation.Valid; import net.gepafin.tendermanagement.config.Translator; +import net.gepafin.tendermanagement.config.jwt.TokenProvider; import net.gepafin.tendermanagement.constants.GepafinConstant; +import net.gepafin.tendermanagement.entities.UserActionEntity; +import net.gepafin.tendermanagement.enums.UserActionContextEnum; +import net.gepafin.tendermanagement.enums.UserActionLogsEnum; import net.gepafin.tendermanagement.enums.UserStatusEnum; import net.gepafin.tendermanagement.model.request.*; import net.gepafin.tendermanagement.model.response.UserSamlResponse; @@ -12,6 +16,7 @@ import net.gepafin.tendermanagement.model.response.UserResponseBean; import net.gepafin.tendermanagement.model.util.JWTToken; import net.gepafin.tendermanagement.model.util.Response; import net.gepafin.tendermanagement.service.UserService; +import net.gepafin.tendermanagement.util.LoggingUtil; import net.gepafin.tendermanagement.web.rest.api.UserApi; import net.gepafin.tendermanagement.web.rest.api.errors.Status; import org.slf4j.Logger; @@ -35,12 +40,27 @@ public class UserApiController implements UserApi { @Autowired private UserService userService; + @Autowired + private LoggingUtil loggingUtil; + + @Autowired + private TokenProvider tokenProvider; + @Override public ResponseEntity> createUser(HttpServletRequest request, String tempToken, @RequestBody UserReq userReq) { log.info("Create User with - Request Body: {}", userReq); + + /** This code is responsible for creating user action logs for the "Create User" operation, even tempToken and userToken is present or not**/ + UserActionEntity userAction = loggingUtil.logUserActionWithoutToken(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.INSERT).actionContext(UserActionContextEnum.CREATE_USER).build()); + JWTToken createdUser = userService.createUser(request, tempToken, userReq); - return ResponseEntity.status(HttpStatus.CREATED) - .body(new Response<>(createdUser, Status.SUCCESS, Translator.toLocale(GepafinConstant.USER_CREATED_SUCCESS_MSG))); + + /** This code is responsible for updating the user action log with new data after token generation.**/ + if (userAction != null) { + loggingUtil.updateUserActionWithTokenDetails(userAction.getId(), createdUser.getToken(), null ); + } + + return ResponseEntity.status(HttpStatus.CREATED).body(new Response<>(createdUser, Status.SUCCESS, Translator.toLocale(GepafinConstant.USER_CREATED_SUCCESS_MSG))); } @Override @@ -48,34 +68,58 @@ public class UserApiController implements UserApi { @PathVariable("userId") Long userId, @Valid @RequestBody UpdateUserReq userReq) { log.info("Update User - User ID: {}, Request Body: {}", userId, userReq); + + /** This code is responsible for "Updating user details" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.UPDATE) + .actionContext(UserActionContextEnum.UPDATE_USER_DETAILS).build()); + UserResponseBean updatedUser = userService.updateUser(request, userId, userReq); + return ResponseEntity.status(HttpStatus.OK) .body(new Response<>(updatedUser, Status.SUCCESS, Translator.toLocale(GepafinConstant.USER_UPDATED_SUCCESS_MSG))); } @Override - public ResponseEntity> getUserById(HttpServletRequest request, - @PathVariable("userId") Long userId) { + public ResponseEntity> getUserById(HttpServletRequest request, @PathVariable("userId") Long userId) { + log.info("Get User by ID - User ID: {}", userId); + + /** This code is responsible for creating user action logs for the "Get user" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.VIEW).actionContext(UserActionContextEnum.GET_USER).build()); + UserResponseBean user = userService.getUserById(request, userId); - return ResponseEntity.status(HttpStatus.OK) - .body(new Response<>(user, Status.SUCCESS, Translator.toLocale(GepafinConstant.GET_USER_SUCCESS_MSG))); + + return ResponseEntity.status(HttpStatus.OK).body(new Response<>(user, Status.SUCCESS, Translator.toLocale(GepafinConstant.GET_USER_SUCCESS_MSG))); } @Override - public ResponseEntity> deleteUser(HttpServletRequest request, - @PathVariable("userId") Long userId) { + public ResponseEntity> deleteUser(HttpServletRequest request, @PathVariable("userId") Long userId) { log.info("Delete User - User ID: {}", userId); + + /** This code is responsible for creating user action logs for the "Delete user" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.DELETE).actionContext(UserActionContextEnum.DELETE_USER).build()); + userService.deleteUser(request, userId); - return ResponseEntity.status(HttpStatus.OK) - .body(new Response<>(null, Status.SUCCESS, Translator.toLocale(GepafinConstant.USER_DELETED_SUCCESS_MSG))); + + return ResponseEntity.status(HttpStatus.OK).body(new Response<>(null, Status.SUCCESS, Translator.toLocale(GepafinConstant.USER_DELETED_SUCCESS_MSG))); } @Override - public ResponseEntity> login(HttpServletRequest request, - @Valid @RequestBody LoginReq loginReq) { + public ResponseEntity> login(HttpServletRequest request, @Valid @RequestBody LoginReq loginReq) { + log.info("User login attempt "); - JWTToken jwtToken = userService.login(loginReq,request); + + /** This code is responsible for creating user action logs for the "LOGIN" operation. **/ + UserActionEntity userAction = loggingUtil.logUserActionWithoutToken( + UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.INSERT).actionContext(UserActionContextEnum.USER_LOGIN).build()); + + JWTToken jwtToken = userService.login(loginReq, request); + + /** This code is responsible for updating the action and version log with new data after token generation.**/ + if (userAction != null) { + loggingUtil.updateUserActionWithTokenDetails(userAction.getId(), jwtToken.getToken(), null); + loggingUtil.updateVersionHistoriesWithTokenDetails(userAction.getId(), jwtToken.getToken()); + } return ResponseEntity.ok(new Response<>(jwtToken, Status.SUCCESS, Translator.toLocale(GepafinConstant.LOGIN_SUCCESS_MSG))); } @Override @@ -106,6 +150,10 @@ public class UserApiController implements UserApi { @Override public ResponseEntity> logoutUser(HttpServletRequest request, HttpServletResponse response) { + + /** This code is responsible for creating user action logs for the "Logout" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.LOGOUT).actionContext(UserActionContextEnum.LOGOUT_USER).build()); + userService.logoutUser(request, response); log.info("User has successfully logged"); @@ -123,24 +171,50 @@ public class UserApiController implements UserApi { public ResponseEntity> getValidUser(HttpServletRequest request) { log.info("Get Valid User Detail"); UserResponseBean user = userService.getValidUser(request); + + /** This code is responsible for creating user action logs for the "Get valid user details." operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.VIEW).actionContext(UserActionContextEnum.GET_VALID_USER_DETAILS).build()); + return ResponseEntity.status(HttpStatus.OK) .body(new Response<>(user, Status.SUCCESS, Translator.toLocale(GepafinConstant.GET_USER_SUCCESS_MSG))); } - + @Override public ResponseEntity> validateExistingUserToken(HttpServletRequest request, String token) { - log.info("User login attempt via spid token"); - JWTToken data = userService.validateExistingUserToken(request, token); - return ResponseEntity.ok(new Response<>(data, Status.SUCCESS, Translator.toLocale(GepafinConstant.TOKEN_VALIDATE_SUCCESS_MSE))); + + log.info("User login attempt via spid token"); + + /** This code is responsible for creating user action logs for the "Validating existing user from spid token" operation. **/ + UserActionEntity userAction = loggingUtil.logUserActionWithoutToken( + UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.VIEW).actionContext(UserActionContextEnum.VALIDATE_EXISTING_USER_WITH_SPID_TOKEN) + .build()); + + JWTToken data = userService.validateExistingUserToken(request, token); + + /** This code is responsible for updating the action and version log with new data.**/ + if (userAction != null) { + loggingUtil.updateUserActionWithTokenDetails(userAction.getId(), data.getToken(), data); + loggingUtil.updateVersionHistoriesWithTokenDetails(userAction.getId(), data.getToken()); + } + + return ResponseEntity.ok(new Response<>(data, Status.SUCCESS, Translator.toLocale(GepafinConstant.TOKEN_VALIDATE_SUCCESS_MSG))); } - + @Override public ResponseEntity> validateNewUserToken(HttpServletRequest request, String token) { - log.info("User validating spid token"); - UserSamlResponse data = userService.validateNewUserToken(request,token); - return ResponseEntity.ok(new Response<>(data, Status.SUCCESS, Translator.toLocale(GepafinConstant.TOKEN_VALIDATE_SUCCESS_MSE))); + + log.info("User validating spid token"); + + /** This code is responsible for creating user action logs for the "Validating new user from spid token" operation. **/ + loggingUtil.logUserActionWithoutToken( + UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.VIEW).actionContext(UserActionContextEnum.VALIDATE_NEW_USER_WITH_SPID_TOKEN).build()); + + UserSamlResponse data = userService.validateNewUserToken(request, token); + + return ResponseEntity.ok(new Response<>(data, Status.SUCCESS, Translator.toLocale(GepafinConstant.TOKEN_VALIDATE_SUCCESS_MSG))); } + @Override public ResponseEntity>> getAllUsers(HttpServletRequest request, Long roleId) { 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 b4c88aa2..67437ae5 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 @@ -1779,4 +1779,11 @@ constraintName="fk_version_history_user_action"/> + + + + + + + From 80ac5c58a3c3c8c966d65acd49a181c5d74777ce Mon Sep 17 00:00:00 2001 From: piyushkag Date: Fri, 22 Nov 2024 17:32:48 +0530 Subject: [PATCH 08/43] Added isDeleted column in user action and version table. --- .../tendermanagement/entities/UserActionEntity.java | 3 +++ .../entities/VersionHistoryEntity.java | 3 +++ .../resources/db/changelog/db.changelog-1.0.0.xml | 12 ++++++++++++ 3 files changed, 18 insertions(+) diff --git a/src/main/java/net/gepafin/tendermanagement/entities/UserActionEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/UserActionEntity.java index 488a6c71..8e1ddd7b 100644 --- a/src/main/java/net/gepafin/tendermanagement/entities/UserActionEntity.java +++ b/src/main/java/net/gepafin/tendermanagement/entities/UserActionEntity.java @@ -40,4 +40,7 @@ public class UserActionEntity extends BaseEntity { @Column(name = "RESPONSE") private String response; + @Column(name = "IS_DELETED") + private String isDeleted; + } \ No newline at end of file diff --git a/src/main/java/net/gepafin/tendermanagement/entities/VersionHistoryEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/VersionHistoryEntity.java index 7a544363..af925f38 100644 --- a/src/main/java/net/gepafin/tendermanagement/entities/VersionHistoryEntity.java +++ b/src/main/java/net/gepafin/tendermanagement/entities/VersionHistoryEntity.java @@ -30,4 +30,7 @@ public class VersionHistoryEntity extends BaseEntity { @Column(name = "USER_ID") private Long userId; + + @Column(name = "IS_DELETED") + private String isDeleted; } 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 67437ae5..8c3c0413 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 @@ -1786,4 +1786,16 @@ + + + + + + + + + + + + From dd6fb536c7d7fea8e9e2a88206761255a23f264d Mon Sep 17 00:00:00 2001 From: piyushkag Date: Fri, 22 Nov 2024 17:41:36 +0530 Subject: [PATCH 09/43] Updated column name. --- .../gepafin/tendermanagement/entities/UserActionEntity.java | 4 ++-- .../tendermanagement/entities/VersionHistoryEntity.java | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/entities/UserActionEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/UserActionEntity.java index 8e1ddd7b..6f85f6ef 100644 --- a/src/main/java/net/gepafin/tendermanagement/entities/UserActionEntity.java +++ b/src/main/java/net/gepafin/tendermanagement/entities/UserActionEntity.java @@ -40,7 +40,7 @@ public class UserActionEntity extends BaseEntity { @Column(name = "RESPONSE") private String response; - @Column(name = "IS_DELETED") - private String isDeleted; + @Column(name = "IS_DELETED", nullable = false) + private Boolean isDeleted = false; } \ No newline at end of file diff --git a/src/main/java/net/gepafin/tendermanagement/entities/VersionHistoryEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/VersionHistoryEntity.java index af925f38..2445fb44 100644 --- a/src/main/java/net/gepafin/tendermanagement/entities/VersionHistoryEntity.java +++ b/src/main/java/net/gepafin/tendermanagement/entities/VersionHistoryEntity.java @@ -31,6 +31,6 @@ public class VersionHistoryEntity extends BaseEntity { @Column(name = "USER_ID") private Long userId; - @Column(name = "IS_DELETED") - private String isDeleted; + @Column(name = "IS_DELETED", nullable = false) + private Boolean isDeleted = false; } From 972e205e94a8e7006086dbf94930b9babe636f89 Mon Sep 17 00:00:00 2001 From: piyushkag Date: Fri, 22 Nov 2024 20:12:18 +0530 Subject: [PATCH 10/43] Updated code. --- .../net/gepafin/tendermanagement/util/LoggingUtil.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/util/LoggingUtil.java b/src/main/java/net/gepafin/tendermanagement/util/LoggingUtil.java index ba7a750d..d3a60884 100644 --- a/src/main/java/net/gepafin/tendermanagement/util/LoggingUtil.java +++ b/src/main/java/net/gepafin/tendermanagement/util/LoggingUtil.java @@ -168,9 +168,10 @@ public class LoggingUtil { String tableName = null; if(versionHistoryRequest.getNewData() != null) { recordId = versionHistoryRequest.getNewData().getId(); - tableName = getTableName(versionHistoryRequest.getNewData().getClass()); + tableName = getTableName(versionHistoryRequest.getNewData().getClass()).toUpperCase(); } else if(versionHistoryRequest.getOldData() != null){ recordId = versionHistoryRequest.getOldData().getId(); + tableName = getTableName(versionHistoryRequest.getOldData().getClass()).toUpperCase(); } logVersionHistory(versionHistoryRequest, recordId, userActionId, tableName); } catch (Exception e) { @@ -185,10 +186,10 @@ public class LoggingUtil { String tableName = null; if(versionHistoryRequest.getNewData() != null) { recordId = versionHistoryRequest.getNewData().getId(); - tableName = getTableName(versionHistoryRequest.getNewData().getClass()); + tableName = getTableName(versionHistoryRequest.getNewData().getClass()).toUpperCase(); } else if(versionHistoryRequest.getOldData() != null){ recordId = versionHistoryRequest.getOldData().getId(); - tableName = getTableName(versionHistoryRequest.getOldData().getClass()); + tableName = getTableName(versionHistoryRequest.getOldData().getClass()).toUpperCase(); } versionHistoryRequest.setNewData(versionHistoryRequest.getNewData()); versionHistoryRequest.setRequest(versionHistoryRequest.getRequest()); From 5581146888bdff0693170a724e4698c55ebd0a86 Mon Sep 17 00:00:00 2001 From: rajesh Date: Sat, 23 Nov 2024 20:02:47 +0530 Subject: [PATCH 11/43] Updated code --- .../gepafin/tendermanagement/dao/FaqDao.java | 8 +++++++ .../enums/UserActionContextEnum.java | 10 ++++++++- .../web/rest/api/impl/FaqApiController.java | 21 +++++++++++++++++++ 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/FaqDao.java b/src/main/java/net/gepafin/tendermanagement/dao/FaqDao.java index ecfb77bd..63ba57df 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/FaqDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/FaqDao.java @@ -59,6 +59,7 @@ public class FaqDao { CallEntity callEntity = callService.validateCall(callId); FaqEntity entity = createOrUpdateFaqEntity(faqRequest, callEntity, userEntity, LookUpDataTypeEnum.FAQ); + FaqEntity oldFaqEntity = Utils.getClonedEntityForData(entity); if (validator.checkIsBeneficiary() && companyId == null) { throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.COMPANY_ID_MANDATORY)); @@ -68,6 +69,10 @@ public class FaqDao { entity.setCompanyId(companyId); } faqRepository.save(entity); + if(entity.getCompanyId()!=null) { + /** This code is responsible for adding a version history log for the "Create FAQ" operation. **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldFaqEntity).newData(entity).build()); + } return convertToFaqResponseBean(entity); } @@ -84,8 +89,11 @@ public class FaqDao { public void deleteFaq(Long id) { FaqEntity faqEntity = validateFaq(id); + FaqEntity oldFaqEntity = Utils.getClonedEntityForData(faqEntity); faqEntity.setIsDeleted(Boolean.TRUE); faqRepository.save(faqEntity); + /** This code is responsible for adding a version history log for the "soft delete faq" operation **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.SOFT_DELETE).oldData(oldFaqEntity).newData(faqEntity).build()); } public FaqEntity validateFaq(Long id) { diff --git a/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java index e2ffcd99..538a60a3 100644 --- a/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java +++ b/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java @@ -22,7 +22,15 @@ public enum UserActionContextEnum { DELETE_USER("DELETE_USER"), VALIDATE_NEW_USER_WITH_SPID_TOKEN("VALIDATE_NEW_USER_WITH_SPID_TOKEN"), VALIDATE_EXISTING_USER_WITH_SPID_TOKEN("VALIDATE_EXISTING_USER_WITH_SPID_TOKEN"), - GET_VALID_USER_DETAILS("GET_VALID_USER_DETAILS"); + GET_VALID_USER_DETAILS("GET_VALID_USER_DETAILS"), + + /** FAQ action context **/ + + CREATE_FAQ("CREATE_FAQ"), + GET_FAQ("GET_FAQ"), + UPDATE_FAQ_DETAILS("UPDATE_FAQ_DETAILS"), + DELETE_FAQ("DELETE_FAQ") + ; private final String value; diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/FaqApiController.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/FaqApiController.java index d905e938..bf6ad305 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/FaqApiController.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/FaqApiController.java @@ -2,10 +2,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.FaqReq; +import net.gepafin.tendermanagement.model.request.UserActionRequest; import net.gepafin.tendermanagement.model.response.FaqResponseBean; import net.gepafin.tendermanagement.model.util.Response; import net.gepafin.tendermanagement.service.FaqService; +import net.gepafin.tendermanagement.util.LoggingUtil; import net.gepafin.tendermanagement.web.rest.api.FaqApi; import net.gepafin.tendermanagement.web.rest.api.errors.Status; import org.springframework.beans.factory.annotation.Autowired; @@ -20,9 +24,14 @@ public class FaqApiController implements FaqApi { @Autowired private FaqService faqService; + @Autowired + private LoggingUtil loggingUtil; @Override public ResponseEntity> createFaq(HttpServletRequest request, Long callId, Long companyId, FaqReq faqRequest) { + /** This code is responsible for creating user action logs for the "Create FAQ" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.INSERT) + .actionContext(UserActionContextEnum.CREATE_FAQ).build()); FaqResponseBean response = faqService.createFaq(request,callId, companyId, faqRequest); return ResponseEntity.status(HttpStatus.CREATED) .body(new Response<>(response, Status.SUCCESS, Translator.toLocale(GepafinConstant.FAQ_CREATED_SUCCESSFULLY))); @@ -30,6 +39,11 @@ public class FaqApiController implements FaqApi { @Override public ResponseEntity> getFaqById(HttpServletRequest request, Long id) { + + /** This code is responsible for creating user action logs for the "get FAQ by id" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.VIEW) + .actionContext(UserActionContextEnum.GET_FAQ).build()); + FaqResponseBean response = faqService.getFaqById(request, id); if (response != null) { return ResponseEntity.status(HttpStatus.OK) @@ -42,6 +56,10 @@ public class FaqApiController implements FaqApi { @Override public ResponseEntity> updateFaq(HttpServletRequest request, Long id, FaqReq faqRequest) { + + /** This code is responsible for "Updating FAQ details" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.UPDATE) + .actionContext(UserActionContextEnum.UPDATE_FAQ_DETAILS).build()); FaqResponseBean response = faqService.updateFaq(request, id, faqRequest); if (response != null) { return ResponseEntity.status(HttpStatus.OK) @@ -54,6 +72,9 @@ public class FaqApiController implements FaqApi { @Override public ResponseEntity> deleteFaq(HttpServletRequest request, Long id) { + /** This code is responsible for creating user action logs for the "Delete FAQ" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.DELETE).actionContext(UserActionContextEnum.DELETE_FAQ).build()); + faqService.deleteFaq(request, id); return ResponseEntity.status(HttpStatus.OK) .body(new Response<>(null, Status.SUCCESS, Translator.toLocale(GepafinConstant.FAQ_DELETED_SUCCESSFULLY))); From b835ee5e5acf1ae93d5a4e2f65b2eb4521e13235 Mon Sep 17 00:00:00 2001 From: piyushkag Date: Sat, 23 Nov 2024 22:27:13 +0530 Subject: [PATCH 12/43] Added audit for application and faq. --- .../tendermanagement/dao/ApplicationDao.java | 252 ++++++++++++------ .../dao/EmailNotificationDao.java | 2 +- .../gepafin/tendermanagement/dao/FaqDao.java | 28 +- .../tendermanagement/dao/ProtocolDao.java | 13 + .../enums/UserActionContextEnum.java | 19 +- .../scheduler/NotificationScheduler.java | 2 +- .../service/impl/ApplicationServiceImpl.java | 6 +- .../api/impl/ApplicationApiController.java | 116 ++++++-- .../web/rest/api/impl/FaqApiController.java | 33 +-- .../web/rest/api/impl/UserApiController.java | 14 +- .../db/changelog/db.changelog-1.0.0.xml | 8 +- 11 files changed, 343 insertions(+), 150 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java index cf2e08c2..9b37ff36 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java @@ -1,6 +1,7 @@ package net.gepafin.tendermanagement.dao; import net.gepafin.tendermanagement.config.Translator; +import net.gepafin.tendermanagement.config.jwt.TokenProvider; import net.gepafin.tendermanagement.constants.GepafinConstant; import net.gepafin.tendermanagement.entities.*; import net.gepafin.tendermanagement.entities.SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum; @@ -8,6 +9,7 @@ import net.gepafin.tendermanagement.enums.*; 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.request.VersionHistoryRequest; import net.gepafin.tendermanagement.model.response.*; import net.gepafin.tendermanagement.repositories.*; import net.gepafin.tendermanagement.service.AmazonS3Service; @@ -20,6 +22,7 @@ import net.gepafin.tendermanagement.service.SystemEmailTemplatesService; import net.gepafin.tendermanagement.service.UserService; 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; @@ -142,6 +145,14 @@ public class ApplicationDao { @Autowired private FormDao formDao; + @Autowired + private LoggingUtil loggingUtil; + + @Autowired + private HttpServletRequest request; + + @Autowired + private TokenProvider tokenProvider; public ApplicationResponseBean createApplication(HttpServletRequest request, ApplicationRequestBean applicationRequestBean, Long formId, Long applicationId) { FormEntity formEntity = formService.validateForm(formId); @@ -157,6 +168,7 @@ public class ApplicationDao { createOrUpdateMultipleFormFields(applicationRequestBean.getFormFields(), applicationFormEntity, formEntity); return getApplicationById(applicationEntity.getId(),formEntity.getId()); } + public void validateDelegation(UserEntity user, CompanyEntity company) { UserWithCompanyEntity userWithCompany = companyService.getUserWithCompanyEntity(user.getId(), company.getId()); @@ -256,12 +268,19 @@ public class ApplicationDao { } public void deleteById(HttpServletRequest request, Long id) { + log.info("Deleting application with ID: {}", id); - ApplicationEntity applicationEntity= validateApplication(id); + ApplicationEntity applicationEntity = validateApplication(id); + ApplicationEntity oldApplicationDataEntity = Utils.getClonedEntityForData(applicationEntity); validator.validateUserWithCompany(request, applicationEntity.getCompany().getId()); applicationEntity.setIsDeleted(true); - applicationEntity=saveApplicationEntity(applicationEntity); + applicationEntity = applicationRepository.save(applicationEntity); + + /** This code is responsible for adding a version history log for the "Delete application" operation. **/ + loggingUtil.addVersionHistory( + VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.SOFT_DELETE).oldData(oldApplicationDataEntity).newData(applicationEntity).build()); + log.info("Application deleted with ID: {}", id); } @@ -385,56 +404,76 @@ public class ApplicationDao { } private ApplicationFormEntity getApplicationFormOrCreate(FormEntity formEntity, ApplicationEntity applicationEntity) { + ApplicationFormEntity applicationFormEntity = applicationFormRepository.findByApplicationIdAndFormId(applicationEntity.getId(), formEntity.getId()); - if(applicationFormEntity == null){ + ApplicationFormEntity oldApplicationFormEntity = Utils.getClonedEntityForData(applicationFormEntity); + if (applicationFormEntity == null) { applicationFormEntity = createApplicationFormEntity(applicationEntity, formEntity); + + /** This code is responsible for adding a version history log for the "Create application form" operation. **/ + loggingUtil.addVersionHistory( + VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.INSERT).oldData(oldApplicationFormEntity).newData(applicationFormEntity) + .build()); } return applicationFormEntity; } - public List createOrUpdateMultipleFormFields(List formFieldResponseBeans, ApplicationFormEntity applicationFormEntity,FormEntity formEntity) { + public List createOrUpdateMultipleFormFields(List formFieldResponseBeans, + ApplicationFormEntity applicationFormEntity, FormEntity formEntity) { + List existingFields = applicationFormFieldRepository.findByApplicationFormId(applicationFormEntity.getId()); - List applicationFormFieldEntity = formFieldResponseBeans.stream() - .map(requestBean -> createOrUpdateApplicationFormField(requestBean, applicationFormEntity,existingFields,formEntity)) + return formFieldResponseBeans.stream().map(requestBean -> createOrUpdateApplicationFormField(requestBean, applicationFormEntity, existingFields, formEntity)) .collect(Collectors.toList()); - return applicationFormFieldEntity; } - public ApplicationFormFieldEntity createOrUpdateApplicationFormField(ApplicationFormFieldRequestBean applicationFormFieldRequestBean, ApplicationFormEntity applicationFormEntity,List applicationFormFieldEntities ,FormEntity formEntity) { + public ApplicationFormFieldEntity createOrUpdateApplicationFormField(ApplicationFormFieldRequestBean applicationFormFieldRequestBean, + ApplicationFormEntity applicationFormEntity, List applicationFormFieldEntities, FormEntity formEntity) { - ApplicationFormFieldEntity applicationFormFieldEntity=null; + ApplicationFormFieldEntity applicationFormFieldEntity = new ApplicationFormFieldEntity(); validateFileUploadDocuments(applicationFormFieldRequestBean, formEntity); + VersionActionTypeEnum actionType = VersionActionTypeEnum.INSERT; - if(applicationFormFieldEntities==null || applicationFormFieldEntities.isEmpty()){ - applicationFormFieldEntity = new ApplicationFormFieldEntity(); + ApplicationFormFieldEntity oldApplicationFormFieldData = null; + + if (applicationFormFieldEntities == null || applicationFormFieldEntities.isEmpty()) { applicationFormFieldEntity.setApplicationForm(applicationFormEntity); - }else { + } else { for (ApplicationFormFieldEntity applicationFormFieldEntity1 : applicationFormFieldEntities) { if (applicationFormFieldEntity1.getFieldId().equals(applicationFormFieldRequestBean.getFieldId())) { applicationFormFieldEntity = applicationFormFieldEntity1; - if(applicationFormEntity.getForm().getId().equals(applicationFormEntity.getApplication().getCall().getInitialForm())){ - validateRequiredFields(applicationFormEntity.getForm(),applicationFormEntity.getApplication(), applicationFormFieldRequestBean.getFieldId()); + oldApplicationFormFieldData = Utils.getClonedEntityForData(applicationFormFieldEntity); + if (applicationFormEntity.getForm().getId().equals(applicationFormEntity.getApplication().getCall().getInitialForm())) { + validateRequiredFields(applicationFormEntity.getForm(), applicationFormEntity.getApplication(), applicationFormFieldRequestBean.getFieldId()); } + actionType = VersionActionTypeEnum.UPDATE; break; } else { - applicationFormFieldEntity = new ApplicationFormFieldEntity(); applicationFormFieldEntity.setApplicationForm(applicationFormEntity); } } } Utils.setIfUpdated(applicationFormFieldEntity::getFieldId, applicationFormFieldEntity::setFieldId, applicationFormFieldRequestBean.getFieldId()); - if(applicationFormFieldRequestBean.getFieldValue() !=null ) { - applicationFormFieldEntity.setFieldValue(Utils.convertObjectToJsonString(applicationFormFieldRequestBean.getFieldValue())); - } - if(applicationFormFieldRequestBean.getFieldValue() ==null ) { + if (applicationFormFieldRequestBean.getFieldValue() != null) { + applicationFormFieldEntity.setFieldValue(Utils.convertObjectToJsonString(applicationFormFieldRequestBean.getFieldValue())); + } else { applicationFormFieldEntity.setFieldValue(null); } - return applicationFormFieldRepository.save(applicationFormFieldEntity); + + ApplicationFormFieldEntity applicationFormField = applicationFormFieldRepository.save(applicationFormFieldEntity); + + /** This code is responsible for adding a version history log for the "Create update application form" operation. **/ + loggingUtil.addVersionHistory( + VersionHistoryRequest.builder().request(request).actionType(actionType).oldData(oldApplicationFormFieldData).newData(applicationFormField).build()); + + log.info("Version history logged for action: {}, Field ID: {}", actionType, applicationFormFieldEntity.getFieldId()); + + return applicationFormField; } + private List validateFileUploadDocuments(ApplicationFormFieldRequestBean applicationFormFieldRequestBean, FormEntity formEntity) { List documentIds=null; // List contentResponseBeans=Utils.convertJsonStringToList(formEntity.getContent(),ContentResponseBean.class); @@ -497,8 +536,14 @@ public class ApplicationDao { applicationFormFieldResponseBean.setUpdatedDate(applicationFormFieldEntity.getUpdatedDate()); return applicationFormFieldResponseBean; } - public ApplicationEntity saveApplicationEntity(ApplicationEntity application){ - ApplicationEntity applicationEntity=applicationRepository.save(application); + + public ApplicationEntity saveApplicationEntity(ApplicationEntity application) { + + ApplicationEntity applicationEntity = applicationRepository.save(application); + + /** This code is responsible for adding a version history log for "Create application" operation. **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.INSERT).oldData(null).newData(applicationEntity).build()); + return applicationEntity; } @@ -654,8 +699,7 @@ public class ApplicationDao { ApplicationEntity applicationEntity = createApplicationEntity(userEntity, call, companyEntity); applicationEntity.setComments(applicationRequest.getComments()); applicationEntity = saveApplicationEntity(applicationEntity); - ApplicationResponse applicationResponse = getApplicationResponse(applicationEntity); - return applicationResponse; + return getApplicationResponse(applicationEntity); } public void checkIfApplicationExists(CallEntity call, CompanyEntity companyEntity, UserEntity userEntity){ Optional applicationEntity=applicationRepository.findByUserIdAndCompanyIdAndCallIdAndIsDeletedFalse(userEntity.getId(), companyEntity.getId(),call.getId()); @@ -665,24 +709,34 @@ public class ApplicationDao { } public ApplicationResponse updateApplicationStatus(HttpServletRequest request, Long applicationId, ApplicationStatusTypeEnum status) { + ApplicationEntity applicationEntity = validateApplication(applicationId); + + //cloned entity for old application data + ApplicationEntity oldApplicationEntity = Utils.getClonedEntityForData(applicationEntity); + UserEntity userEntity = userService.validateUser(applicationEntity.getUserId()); validator.validateUserWithCompany(request, applicationEntity.getCompany().getId()); if (ApplicationStatusTypeEnum.SUBMIT.getValue().equals(applicationEntity.getStatus())) { throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.APPLICATION_SUBMITTED_CANNOT_CHANGE)); } - if(Boolean.TRUE.equals(applicationEntity.getStatus().equals(status.getValue()))){ - throw new CustomValidationException(Status.BAD_REQUEST,Translator.toLocale(GepafinConstant.APPLICATION_ALREADY_IN_PREVIOUS_STATUS)); + if (Boolean.TRUE.equals(applicationEntity.getStatus().equals(status.getValue()))) { + throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.APPLICATION_ALREADY_IN_PREVIOUS_STATUS)); } - if (status.equals(ApplicationStatusTypeEnum.SUBMIT) && Boolean.TRUE.equals(applicationEntity.getStatus().equals(ApplicationStatusTypeEnum.READY.getValue()))) { + if (status.equals(ApplicationStatusTypeEnum.SUBMIT) && Boolean.TRUE.equals(applicationEntity.getStatus().equals(ApplicationStatusTypeEnum.READY.getValue()))) { callService.validatePublishedCall(applicationEntity.getCall().getId(), userEntity.getHub().getId()); Long protocolNumber = protocolDao.getProtocolNumber(userEntity.getHub()); - ProtocolEntity protocolEntity = protocolDao.createProtocolEntity(applicationEntity,protocolNumber, userEntity.getHub().getId()); + ProtocolEntity protocolEntity = protocolDao.createProtocolEntity(applicationEntity, protocolNumber, userEntity.getHub().getId()); applicationEntity.setProtocol(protocolEntity); applicationEntity.setStatus(ApplicationStatusTypeEnum.SUBMIT.getValue()); applicationEntity.setSubmissionDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); - applicationEntity = saveApplicationEntity(applicationEntity); + applicationEntity = applicationRepository.save(applicationEntity); + + /** This code is responsible for adding a version history log for "Update application status" operation. **/ + loggingUtil.addVersionHistory( + VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplicationEntity).newData(applicationEntity).build()); + sendMailToUserAndCompany(userEntity, applicationEntity); sendMailTodefaultSystemAndGepafin(userEntity, applicationEntity); applicationEntity.setStatus(status.getValue()); @@ -690,13 +744,16 @@ public class ApplicationDao { if (status.equals(ApplicationStatusTypeEnum.DRAFT) && Boolean.TRUE.equals(applicationEntity.getStatus().equals(ApplicationStatusTypeEnum.AWAITING.getValue()))) { applicationEntity.setStatus(status.getValue()); } - applicationEntity = saveApplicationEntity(applicationEntity); - + applicationEntity = applicationRepository.save(applicationEntity); + if (!status.equals(ApplicationStatusTypeEnum.SUBMIT)) { + /** This code is responsible for adding a version history log for "Update application status" operation. **/ + loggingUtil.addVersionHistory( + VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplicationEntity).newData(applicationEntity).build()); + } return getApplicationResponse(applicationEntity); } - public Integer calculateProgress(Long totalSteps, Long completedSteps) { if (FieldValidator.isNullOrZero(totalSteps)) { throw new CustomValidationException(Status.BAD_REQUEST,Translator.toLocale(GepafinConstant.TOTAL_STEPS_NOT_BE_ZERO)); @@ -765,7 +822,17 @@ public class ApplicationDao { if (nextApplicationFormEntity != null) { List nextApplicationFormFieldEntities = applicationFormFieldRepository.findByApplicationFormId(nextApplicationFormEntity.getId()); + + nextApplicationFormFieldEntities.forEach(applicationFormFieldEntityToDelete -> + /** This code is responsible for adding a version history log for "Deleting application form field" operation. **/ + loggingUtil.addVersionHistory( + VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.DELETE).oldData(applicationFormFieldEntityToDelete).build())); + applicationFormFieldRepository.deleteAll(nextApplicationFormFieldEntities); + + /** This code is responsible for adding a version history log for the "Deleting next application form" operation. **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.DELETE).oldData(nextApplicationFormEntity).build()); + applicationFormRepository.delete(nextApplicationFormEntity); } } @@ -853,30 +920,46 @@ public class ApplicationDao { emailNotificationDao.sendMail(hub.getId(), subject, body, List.of(rinaldoEmail)); } - public ApplicationSignedDocumentResponse uploadSignedDocument(HttpServletRequest request, Long applicationId, - MultipartFile file) { - ApplicationEntity applicationEntity = validateApplication(applicationId); - validator.validateUserWithCompany(request, applicationEntity.getCompany().getId()); + + public ApplicationSignedDocumentResponse uploadSignedDocument(HttpServletRequest request, Long applicationId, MultipartFile file) { + + ApplicationEntity applicationEntity = validateApplication(applicationId); + //cloned entity for old data + ApplicationEntity oldApplicationData = Utils.getClonedEntityForData(applicationEntity); + + validator.validateUserWithCompany(request, applicationEntity.getCompany().getId()); validateFileTypeForCall(file, applicationEntity); - ApplicationSignedDocumentEntity applicationSignedDocument = applicationSignedDocumentRepository - .findByApplicationIdAndStatus(applicationId, ApplicationSignedDocumentStatusEnum.ACTIVE.getValue()); - if (applicationSignedDocument != null) { - throw new CustomValidationException(Status.BAD_REQUEST,Translator.toLocale(GepafinConstant.APPLICATION_ALREADY_ASSIGNED)); -// applicationSignedDocument.setStatus(ApplicationSignedDocumentStatusEnum.INACTIVE.getValue()); -// applicationSignedDocumentRepository.save(applicationSignedDocument); - } - UploadFileOnAmazonS3Response uploadFileOnAmazonS3 = uploadFileOnAmazonS3ForUserSignedDocument(file, - applicationEntity.getCall().getId(), applicationId); + ApplicationSignedDocumentEntity applicationSignedDocument = applicationSignedDocumentRepository.findByApplicationIdAndStatus(applicationId, + ApplicationSignedDocumentStatusEnum.ACTIVE.getValue()); + //cloned entity for old data + ApplicationSignedDocumentEntity oldApplicationSingedDocumentData = Utils.getClonedEntityForData(applicationSignedDocument); + + if (applicationSignedDocument != null) { + throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.APPLICATION_ALREADY_ASSIGNED)); + // applicationSignedDocument.setStatus(ApplicationSignedDocumentStatusEnum.INACTIVE.getValue()); + // applicationSignedDocumentRepository.save(applicationSignedDocument); + } + UploadFileOnAmazonS3Response uploadFileOnAmazonS3 = uploadFileOnAmazonS3ForUserSignedDocument(file, applicationEntity.getCall().getId(), applicationId); applicationSignedDocument = new ApplicationSignedDocumentEntity(); - applicationSignedDocument.setApplication(applicationEntity); - applicationSignedDocument.setFileName(uploadFileOnAmazonS3.getFileName()); - applicationSignedDocument.setFilePath(uploadFileOnAmazonS3.getFilePath()); - applicationSignedDocument.setStatus(ApplicationSignedDocumentStatusEnum.ACTIVE.getValue()); - applicationSignedDocumentRepository.save(applicationSignedDocument); + applicationSignedDocument.setApplication(applicationEntity); + applicationSignedDocument.setFileName(uploadFileOnAmazonS3.getFileName()); + applicationSignedDocument.setFilePath(uploadFileOnAmazonS3.getFilePath()); + applicationSignedDocument.setStatus(ApplicationSignedDocumentStatusEnum.ACTIVE.getValue()); + applicationSignedDocument = applicationSignedDocumentRepository.save(applicationSignedDocument); + + /** This code is responsible for adding a version history log for the "assign application document" operation. **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.INSERT).oldData(oldApplicationSingedDocumentData) + .newData(applicationSignedDocument).build()); + applicationEntity.setStatus(ApplicationStatusTypeEnum.READY.getValue()); - applicationRepository.save(applicationEntity); - return convertApplicationSignedDocumentToApplicationSignedDocumentResponse(applicationSignedDocument); - } + applicationEntity = applicationRepository.save(applicationEntity); + + /** This code is responsible for adding a version history log for the "Create Call" operation. **/ + loggingUtil.addVersionHistory( + VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplicationData).newData(applicationEntity).build()); + + return convertApplicationSignedDocumentToApplicationSignedDocumentResponse(applicationSignedDocument); + } private void validateFileTypeForCall(MultipartFile file, ApplicationEntity applicationEntity) { List validCallIds = Arrays.asList(callId.split(",")); @@ -942,39 +1025,56 @@ public class ApplicationDao { } return convertApplicationSignedDocumentToApplicationSignedDocumentResponse(applicationSignedDocument); } - - public void deleteSignedDocument(HttpServletRequest request, Long applicationId) { - ApplicationEntity applicationEntity = validateApplication(applicationId); - validator.validateUserWithCompany(request, applicationEntity.getCompany().getId()); - - ApplicationSignedDocumentEntity applicationSignedDocument = applicationSignedDocumentRepository - .findByApplicationIdAndStatus(applicationId, ApplicationSignedDocumentStatusEnum.ACTIVE.getValue()); - if(applicationSignedDocument == null) { - throw new ResourceNotFoundException(Status.NOT_FOUND, - Translator.toLocale(GepafinConstant.APPLICATION_SIGNED_DOCUMENT_NOT_FOUND)); - } - applicationSignedDocument.setStatus(ApplicationSignedDocumentStatusEnum.INACTIVE.getValue()); - applicationSignedDocumentRepository.save(applicationSignedDocument); - } + + public void deleteSignedDocument(HttpServletRequest request, Long applicationId) { + + ApplicationEntity applicationEntity = validateApplication(applicationId); + validator.validateUserWithCompany(request, applicationEntity.getCompany().getId()); + + ApplicationSignedDocumentEntity applicationSignedDocument = applicationSignedDocumentRepository.findByApplicationIdAndStatus(applicationId, + ApplicationSignedDocumentStatusEnum.ACTIVE.getValue()); + //cloned entity for old data + ApplicationSignedDocumentEntity oldApplicationSignedDocument = Utils.getClonedEntityForData(applicationSignedDocument); + if (applicationSignedDocument == null) { + throw new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.APPLICATION_SIGNED_DOCUMENT_NOT_FOUND)); + } + applicationSignedDocument.setStatus(ApplicationSignedDocumentStatusEnum.INACTIVE.getValue()); + applicationSignedDocument = applicationSignedDocumentRepository.save(applicationSignedDocument); + + /** This code is responsible for adding a version history log for the "Delete signed document" operation. **/ + loggingUtil.addVersionHistory( + VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplicationSignedDocument).newData(applicationSignedDocument) + .build()); + } public ApplicationResponse validateApplication(HttpServletRequest request, Long applicationId) { + ApplicationEntity applicationEntity = validateApplication(applicationId); - UserEntity userEntity = userService.validateUser(applicationEntity.getUserId()); + + ApplicationEntity oldApplicationEntity = Utils.getClonedEntityForData(applicationEntity); + + userService.validateUser(applicationEntity.getUserId()); validator.validateUserWithCompany(request, applicationEntity.getCompany().getId()); if (Boolean.FALSE.equals(ApplicationStatusTypeEnum.DRAFT.getValue().equals(applicationEntity.getStatus()))) { throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.APPLICATION_NOT_IN_DRAFT_STATUS)); } - List flowEdgesList = flowEdgesRepository.findByCallId(applicationEntity.getCall().getId()); - Long totalSteps=flowFormDao.calculateTotalSteps(flowEdgesList); - Integer completedSteps=flowFormDao.getCompletedSteps(applicationEntity); - if (totalSteps.intValue() != completedSteps) { - throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.APPLICATION_IS_INCOMPLETE_MSG)); - } + List flowEdgesList = flowEdgesRepository.findByCallId(applicationEntity.getCall().getId()); + Long totalSteps = flowFormDao.calculateTotalSteps(flowEdgesList); + Integer completedSteps = flowFormDao.getCompletedSteps(applicationEntity); + if (totalSteps.intValue() != completedSteps) { + throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.APPLICATION_IS_INCOMPLETE_MSG)); + } + + applicationEntity.setStatus(ApplicationStatusTypeEnum.AWAITING.getValue()); + applicationEntity = applicationRepository.save(applicationEntity); + + /** This code is responsible for adding a version history log for "Update application status or other details" operation. **/ + loggingUtil.addVersionHistory( + VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplicationEntity).newData(applicationEntity).build()); - applicationEntity.setStatus(ApplicationStatusTypeEnum.AWAITING.getValue()); - applicationEntity = saveApplicationEntity(applicationEntity); return getApplicationResponse(applicationEntity); } + public byte[] downloadApplicationDocumentsAsZip(HttpServletRequest request, Long applicationId) { ApplicationEntity applicationEntity = validateApplication(applicationId); validateAssignedUser(request, applicationId); diff --git a/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java index ae19c380..7fea627a 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java @@ -163,7 +163,7 @@ public class EmailNotificationDao { EmailConfig emailConfig = retrieveEmailConfig(hubId); EmailService emailService = emailServiceFactory.getEmailService(emailConfig.getEmailServiceType()); - emailService.sendEmail(subject, body, recipientEmails, emailConfig); +// emailService.sendEmail(subject, body, recipientEmails, emailConfig); } public EmailConfig retrieveEmailConfig(Long hubId) { diff --git a/src/main/java/net/gepafin/tendermanagement/dao/FaqDao.java b/src/main/java/net/gepafin/tendermanagement/dao/FaqDao.java index 63ba57df..3cad69b9 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/FaqDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/FaqDao.java @@ -56,20 +56,20 @@ public class FaqDao { LoggingUtil loggingUtil; public FaqResponseBean createFaq(FaqReq faqRequest, UserEntity userEntity, Long callId, Long companyId) { + CallEntity callEntity = callService.validateCall(callId); - FaqEntity entity = createOrUpdateFaqEntity(faqRequest, callEntity, userEntity, - LookUpDataTypeEnum.FAQ); + FaqEntity entity = createOrUpdateFaqEntity(faqRequest, callEntity, userEntity, LookUpDataTypeEnum.FAQ); FaqEntity oldFaqEntity = Utils.getClonedEntityForData(entity); if (validator.checkIsBeneficiary() && companyId == null) { - throw new CustomValidationException(Status.VALIDATION_ERROR, - Translator.toLocale(GepafinConstant.COMPANY_ID_MANDATORY)); + throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.COMPANY_ID_MANDATORY)); } - if(companyId!=null) { + if (companyId != null) { companyService.validateCompany(companyId); entity.setCompanyId(companyId); } faqRepository.save(entity); - if(entity.getCompanyId()!=null) { + + if (entity.getCompanyId() != null) { /** This code is responsible for adding a version history log for the "Create FAQ" operation. **/ loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldFaqEntity).newData(entity).build()); } @@ -88,12 +88,15 @@ public class FaqDao { } public void deleteFaq(Long id) { + FaqEntity faqEntity = validateFaq(id); FaqEntity oldFaqEntity = Utils.getClonedEntityForData(faqEntity); faqEntity.setIsDeleted(Boolean.TRUE); faqRepository.save(faqEntity); + /** This code is responsible for adding a version history log for the "soft delete faq" operation **/ - loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.SOFT_DELETE).oldData(oldFaqEntity).newData(faqEntity).build()); + loggingUtil.addVersionHistory( + VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.SOFT_DELETE).oldData(oldFaqEntity).newData(faqEntity).build()); } public FaqEntity validateFaq(Long id) { @@ -107,16 +110,14 @@ public class FaqDao { .toList(); } - - public FaqEntity createOrUpdateFaqEntity(FaqReq faqReq, CallEntity callEntity, UserEntity userEntity, - LookUpDataTypeEnum type) { + public FaqEntity createOrUpdateFaqEntity(FaqReq faqReq, CallEntity callEntity, UserEntity userEntity, LookUpDataTypeEnum type) { + FaqEntity faqEntity = null; FaqEntity oldFaqEntity = null; VersionActionTypeEnum actionType = VersionActionTypeEnum.INSERT; if (isExistingFaq(faqReq)) { faqEntity = faqRepository.findByIdAndCallIdAndIsDeletedFalse(faqReq.getId(), callEntity.getId()) - .orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND, - Translator.toLocale(GepafinConstant.FAQ_NOT_FOUND))); + .orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.FAQ_NOT_FOUND))); oldFaqEntity = Utils.getClonedEntityForData(faqEntity); actionType = VersionActionTypeEnum.UPDATE; } else { @@ -130,8 +131,7 @@ public class FaqDao { faqEntity.setIsDeleted(false); actionType = VersionActionTypeEnum.INSERT; } - if (faqReq.getResponse() != null && (faqEntity.getResponse() == null - || Boolean.FALSE.equals(faqReq.getResponse().equals(faqEntity.getResponse())))) { + if (faqReq.getResponse() != null && (faqEntity.getResponse() == null || Boolean.FALSE.equals(faqReq.getResponse().equals(faqEntity.getResponse())))) { faqEntity.setResponseDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); } setIfUpdated(faqEntity::getTitle, faqEntity::setTitle, faqReq.getTitle()); diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ProtocolDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ProtocolDao.java index 97ecde18..a7606c9a 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ProtocolDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ProtocolDao.java @@ -3,6 +3,10 @@ package net.gepafin.tendermanagement.dao; import java.time.LocalDateTime; import java.time.LocalTime; +import jakarta.servlet.http.HttpServletRequest; +import net.gepafin.tendermanagement.enums.VersionActionTypeEnum; +import net.gepafin.tendermanagement.model.request.VersionHistoryRequest; +import net.gepafin.tendermanagement.util.LoggingUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; @@ -23,6 +27,11 @@ public class ProtocolDao { @Value("${default.hub.uuid}") private String defaultHubUuid; + @Autowired + private LoggingUtil loggingUtil; + + @Autowired + private HttpServletRequest request; public Long getProtocolNumber(HubEntity hubEntity) { Long maxProtocolNumber = protocolRepository.findMaxProtocolNumberAndHubId(hubEntity.getId()); @@ -43,6 +52,10 @@ public class ProtocolDao { protocolEntity.setApplicationId(applicationEntity.getId()); protocolEntity.setHubId(hubId); protocolRepository.save(protocolEntity); + + /** This code is responsible for adding a version history log for "create protocol" operation. **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.INSERT).oldData(null).newData(protocolEntity).build()); + return protocolEntity; } } diff --git a/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java index 538a60a3..9fe07bc0 100644 --- a/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java +++ b/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java @@ -23,14 +23,27 @@ public enum UserActionContextEnum { VALIDATE_NEW_USER_WITH_SPID_TOKEN("VALIDATE_NEW_USER_WITH_SPID_TOKEN"), VALIDATE_EXISTING_USER_WITH_SPID_TOKEN("VALIDATE_EXISTING_USER_WITH_SPID_TOKEN"), GET_VALID_USER_DETAILS("GET_VALID_USER_DETAILS"), + GET_ALL_USERS_BY_ROLE("GET_ALL_USERS_BY_ROLE"), + + /** application action context **/ + GET_APPLICATION("GET_APPLICATION"), + CREATE_UPDATE_APPLICATION_FORM("CREATE_UPDATE_APPLICATION_FORM"), + CREATE_APPLICATION("CREATE_APPLICATION"), + DELETE_APPLICATION("DELETE_APPLICATION"), + GET_ALL_APPLICATION("GET_ALL_APPLICATION"), + UPDATE_APPLICATION_STATUS("UPDATE_APPLICATION_STATUS"), + VALIDATE_APPLICATION("VALIDATE_APPLICATION"), + UPLOAD_SIGNED_DOCUMENT("UPLOAD_SIGNED_DOCUMENT"), + DOWNLOAD_PDF("DOWNLOAD_PDF"), + GET_SIGNED_DOCUMENT("GET_SIGNED_DOCUMENT"), + GET_NEXT_PREVIOUS_FORM("GET_NEXT_PREVIOUS_FORM"), + DOWNLOAD_APPLICATION_DOC_ZIP("DOWNLOAD_APPLICATION_DOC_ZIP"), /** FAQ action context **/ - CREATE_FAQ("CREATE_FAQ"), GET_FAQ("GET_FAQ"), UPDATE_FAQ_DETAILS("UPDATE_FAQ_DETAILS"), - DELETE_FAQ("DELETE_FAQ") - ; + DELETE_FAQ("DELETE_FAQ"); private final String value; diff --git a/src/main/java/net/gepafin/tendermanagement/scheduler/NotificationScheduler.java b/src/main/java/net/gepafin/tendermanagement/scheduler/NotificationScheduler.java index 93d41c98..0426fc70 100644 --- a/src/main/java/net/gepafin/tendermanagement/scheduler/NotificationScheduler.java +++ b/src/main/java/net/gepafin/tendermanagement/scheduler/NotificationScheduler.java @@ -29,7 +29,7 @@ public class NotificationScheduler { @Autowired EmailNotificationDao emailNotificationDao; - @Scheduled(cron = "0 0 1 * * ?") +// @Scheduled(cron = "0 0 1 * * ?") void sendNotificationForRejectedApplicationToBeneficiary() { List applicationsList = applicationRepository.findByIsDeletedFalse(); diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationServiceImpl.java index 0fec17a7..87cea90b 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationServiceImpl.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationServiceImpl.java @@ -76,12 +76,12 @@ public class ApplicationServiceImpl implements ApplicationService { validator.validateUserWithCompany(request, applicationEntity.getCompany().getId()); return flowFormDao.getNextOrPreviousForm(applicationEntity, formId, action); } - + @Override @Transactional(rollbackFor = Exception.class) public ApplicationResponse updateApplicationStatus(HttpServletRequest request, Long applicationId, ApplicationStatusTypeEnum status) { - return applicationDao.updateApplicationStatus(request, applicationId, status); - + + return applicationDao.updateApplicationStatus(request, applicationId, status); } @Override 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 index 958d8096..3223dda7 100644 --- 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 @@ -3,10 +3,13 @@ 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.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.request.UserActionRequest; import net.gepafin.tendermanagement.model.response.ApplicationGetResponseBean; import net.gepafin.tendermanagement.model.response.ApplicationResponse; import net.gepafin.tendermanagement.model.response.ApplicationResponseBean; @@ -15,6 +18,7 @@ import net.gepafin.tendermanagement.model.response.NextOrPreviousFormResponse; import net.gepafin.tendermanagement.model.util.Response; import net.gepafin.tendermanagement.service.ApplicationService; import net.gepafin.tendermanagement.service.PdfService; +import net.gepafin.tendermanagement.util.LoggingUtil; import net.gepafin.tendermanagement.web.rest.api.ApplicationApi; import net.gepafin.tendermanagement.web.rest.api.errors.Status; import org.slf4j.LoggerFactory; @@ -43,9 +47,19 @@ public class ApplicationApiController implements ApplicationApi { @Autowired private PdfService pdfService; + @Autowired + private LoggingUtil loggingUtil; + @Override - public ResponseEntity> createApplication(HttpServletRequest request, ApplicationRequestBean applicationRequestBean, Long applicationId, Long formId) { + public ResponseEntity> createApplication(HttpServletRequest request, ApplicationRequestBean applicationRequestBean, Long applicationId, + Long formId) { + + /** This code is responsible for creating user action logs for the "Create or update application form" operation. **/ + loggingUtil.logUserAction( + UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.UPDATE).actionContext(UserActionContextEnum.CREATE_UPDATE_APPLICATION_FORM).build()); + ApplicationResponseBean applicationResponseBean = applicationService.createApplication(request, applicationRequestBean, applicationId, formId); + return ResponseEntity.status(HttpStatus.CREATED) .body(new Response<>(applicationResponseBean, Status.SUCCESS, Translator.toLocale(GepafinConstant.APPLICATION_CREATED_SUCCESS_MSG))); } @@ -54,38 +68,63 @@ public class ApplicationApiController implements ApplicationApi { public ResponseEntity> getApplicationByFormId(HttpServletRequest request , Long applicationId, Long formId) { log.info("Get Application by ID - Application ID: {}", applicationId); + + /** This code is responsible for creating user action logs for the "Get Application" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.VIEW).actionContext(UserActionContextEnum.GET_APPLICATION).build()); + 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) { + public ResponseEntity> deleteApplication(HttpServletRequest request, Long applicationId) { + log.info("Delete Application - Application ID: {}", applicationId); + + /** This code is responsible for creating user action logs for the "Delete Application" operation. **/ + loggingUtil.logUserAction( + UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.DELETE).actionContext(UserActionContextEnum.DELETE_APPLICATION).build()); + applicationService.deleteApplication(request, applicationId); - return ResponseEntity.status(HttpStatus.OK) - .body(new Response<>(null, Status.SUCCESS, Translator.toLocale(GepafinConstant.DELETE_APPLICATION_SUCCESS_MSG))); + + return ResponseEntity.status(HttpStatus.OK).body(new Response<>(null, Status.SUCCESS, Translator.toLocale(GepafinConstant.DELETE_APPLICATION_SUCCESS_MSG))); } @Override public ResponseEntity> createApplicationByCallId(HttpServletRequest request, Long companyId, ApplicationRequest applicationRequest, Long callId) { + + /** This code is responsible for creating user action logs for the "Create application" operation. **/ + loggingUtil.logUserAction( + UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.INSERT).actionContext(UserActionContextEnum.CREATE_APPLICATION).build()); + ApplicationResponse applicationResponseBean = applicationService.createApplication(request, companyId, 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, Long callId, Long companyId, List statusList) { - List applications = applicationService.getAllApplications(request, callId, companyId,statusList); + public ResponseEntity>> getAllApplications(HttpServletRequest request, Long callId, Long companyId, + List statusList) { + + /** This code is responsible for creating user action logs for the "Get application" operation. **/ + loggingUtil.logUserAction( + UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.VIEW).actionContext(UserActionContextEnum.GET_ALL_APPLICATION).build()); + + List applications = applicationService.getAllApplications(request, callId, companyId, statusList); log.info("Get All Applications"); - return ResponseEntity.status(HttpStatus.OK) - .body(new Response<>(applications, Status.SUCCESS, Translator.toLocale(GepafinConstant.GET_APPLICATION_SUCCESS_MSG))); + + 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) { + + /** This code is responsible for creating user action logs for the "get next or previous form" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.VIEW).actionContext(UserActionContextEnum.GET_NEXT_PREVIOUS_FORM).build()); + NextOrPreviousFormResponse data = applicationService.getNextOrPreviousForm(request, applicationId, formId, action); log.info("Get Next Or Previous Form "); return ResponseEntity.status(HttpStatus.OK) @@ -93,15 +132,24 @@ public class ApplicationApiController implements ApplicationApi { } @Override - public ResponseEntity> updateApplicationStatus(HttpServletRequest request, Long applicationId, - ApplicationStatusTypeEnum status) { + public ResponseEntity> updateApplicationStatus(HttpServletRequest request, Long applicationId, ApplicationStatusTypeEnum status) { + + /** This code is responsible for creating user action logs for the "update application status" operation. **/ + loggingUtil.logUserAction( + UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.UPDATE).actionContext(UserActionContextEnum.UPDATE_APPLICATION_STATUS).build()); + ApplicationResponse applicationResponse = applicationService.updateApplicationStatus(request, applicationId, status); + return ResponseEntity.status(HttpStatus.OK) .body(new Response<>(applicationResponse, Status.SUCCESS, Translator.toLocale(GepafinConstant.APPLICATION_STATUS_UPDATED_SUCCESSFULLY))); } @Override public ResponseEntity generateApplicationPdf(HttpServletRequest request, Long applicationId) { + + /** This code is responsible for creating user action logs for the "Generate pdf for application" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.DOWNLOAD).actionContext(UserActionContextEnum.DOWNLOAD_PDF).build()); + byte[] pdfBytes = pdfService.generatePdf(request, applicationId); // Prepare headers for downloading the PDF @@ -114,23 +162,31 @@ public class ApplicationApiController implements ApplicationApi { .contentType(MediaType.APPLICATION_PDF) .body(pdfBytes); } - + @Override - public ResponseEntity> uploadSignedDocument(HttpServletRequest request, - Long applicationId, MultipartFile file) { - log.info("upload signed document applicationId: {}", applicationId); - ApplicationSignedDocumentResponse response = applicationService.uploadSignedDocument(request, applicationId, file); - return ResponseEntity.status(HttpStatus.OK) - .body(new Response<>(response, Status.SUCCESS, Translator.toLocale(GepafinConstant.SIGNED_DOCUMENT_FILE_UPLOAD_SUCCESS))); - } - + public ResponseEntity> uploadSignedDocument(HttpServletRequest request, Long applicationId, MultipartFile file) { + + log.info("upload signed document applicationId: {}", applicationId); + + /** This code is responsible for creating user action logs for the "Upload signed document" operation. **/ + loggingUtil.logUserAction( + UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.INSERT).actionContext(UserActionContextEnum.UPLOAD_SIGNED_DOCUMENT).build()); + + ApplicationSignedDocumentResponse response = applicationService.uploadSignedDocument(request, applicationId, file); + return ResponseEntity.status(HttpStatus.OK).body(new Response<>(response, Status.SUCCESS, Translator.toLocale(GepafinConstant.SIGNED_DOCUMENT_FILE_UPLOAD_SUCCESS))); + } + @Override - public ResponseEntity> getSignedDocument(HttpServletRequest request, - Long applicationId) { - ApplicationSignedDocumentResponse response = applicationService.getSignedDocument(request, applicationId); - log.info("get signed document applicationId: {}", applicationId); - return ResponseEntity.status(HttpStatus.OK) - .body(new Response<>(response, Status.SUCCESS, Translator.toLocale(GepafinConstant.GET_SIGNED_DOCUMENT_FILE_SUCCESS))); + public ResponseEntity> getSignedDocument(HttpServletRequest request, Long applicationId) { + + /** This code is responsible for creating user action logs for the "Get signed document" operation. **/ + loggingUtil.logUserAction( + UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.VIEW).actionContext(UserActionContextEnum.GET_SIGNED_DOCUMENT).build()); + + ApplicationSignedDocumentResponse response = applicationService.getSignedDocument(request, applicationId); + + log.info("get signed document applicationId: {}", applicationId); + return ResponseEntity.status(HttpStatus.OK).body(new Response<>(response, Status.SUCCESS, Translator.toLocale(GepafinConstant.GET_SIGNED_DOCUMENT_FILE_SUCCESS))); } // @Override @@ -144,12 +200,20 @@ public class ApplicationApiController implements ApplicationApi { @Override public ResponseEntity> validateApplication(HttpServletRequest request, Long applicationId) { + + /** This code is responsible for creating user action logs for the "validate application" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.UPDATE).actionContext(UserActionContextEnum.VALIDATE_APPLICATION).build()); + ApplicationResponse applicationResponse = applicationService.validateApplication(request, applicationId); return ResponseEntity.status(HttpStatus.OK) .body(new Response<>(applicationResponse, Status.SUCCESS, Translator.toLocale(GepafinConstant.APPLICATION_STATUS_UPDATED_SUCCESSFULLY))); } @Override public ResponseEntity downloadApplicationDocumentsAsZip(HttpServletRequest request, Long applicationId) { + + /** This code is responsible for creating user action logs for the "download application document as zip" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.DOWNLOAD).actionContext(UserActionContextEnum.DOWNLOAD_APPLICATION_DOC_ZIP).build()); + byte[] zipFile = applicationService.downloadApplicationDocumentsAsZip(request, applicationId); HttpHeaders headers = new HttpHeaders(); diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/FaqApiController.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/FaqApiController.java index bf6ad305..869d3c68 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/FaqApiController.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/FaqApiController.java @@ -29,28 +29,25 @@ public class FaqApiController implements FaqApi { @Override public ResponseEntity> createFaq(HttpServletRequest request, Long callId, Long companyId, FaqReq faqRequest) { + /** This code is responsible for creating user action logs for the "Create FAQ" operation. **/ - loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.INSERT) - .actionContext(UserActionContextEnum.CREATE_FAQ).build()); - FaqResponseBean response = faqService.createFaq(request,callId, companyId, faqRequest); - return ResponseEntity.status(HttpStatus.CREATED) - .body(new Response<>(response, Status.SUCCESS, Translator.toLocale(GepafinConstant.FAQ_CREATED_SUCCESSFULLY))); + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.INSERT).actionContext(UserActionContextEnum.CREATE_FAQ).build()); + + FaqResponseBean response = faqService.createFaq(request, callId, companyId, faqRequest); + return ResponseEntity.status(HttpStatus.CREATED).body(new Response<>(response, Status.SUCCESS, Translator.toLocale(GepafinConstant.FAQ_CREATED_SUCCESSFULLY))); } @Override public ResponseEntity> getFaqById(HttpServletRequest request, Long id) { /** This code is responsible for creating user action logs for the "get FAQ by id" operation. **/ - loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.VIEW) - .actionContext(UserActionContextEnum.GET_FAQ).build()); + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.VIEW).actionContext(UserActionContextEnum.GET_FAQ).build()); FaqResponseBean response = faqService.getFaqById(request, id); if (response != null) { - return ResponseEntity.status(HttpStatus.OK) - .body(new Response<>(response, Status.SUCCESS, Translator.toLocale(GepafinConstant.FAQ_FETCHED_SUCCESSFULLY))); + return ResponseEntity.status(HttpStatus.OK).body(new Response<>(response, Status.SUCCESS, Translator.toLocale(GepafinConstant.FAQ_FETCHED_SUCCESSFULLY))); } else { - return ResponseEntity.status(HttpStatus.NOT_FOUND) - .body(new Response<>(null, Status.NOT_FOUND, Translator.toLocale(GepafinConstant.FAQ_NOT_FOUND))); + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(new Response<>(null, Status.NOT_FOUND, Translator.toLocale(GepafinConstant.FAQ_NOT_FOUND))); } } @@ -58,25 +55,23 @@ public class FaqApiController implements FaqApi { public ResponseEntity> updateFaq(HttpServletRequest request, Long id, FaqReq faqRequest) { /** This code is responsible for "Updating FAQ details" operation. **/ - loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.UPDATE) - .actionContext(UserActionContextEnum.UPDATE_FAQ_DETAILS).build()); + loggingUtil.logUserAction( + UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.UPDATE).actionContext(UserActionContextEnum.UPDATE_FAQ_DETAILS).build()); FaqResponseBean response = faqService.updateFaq(request, id, faqRequest); if (response != null) { - return ResponseEntity.status(HttpStatus.OK) - .body(new Response<>(response, Status.SUCCESS, Translator.toLocale(GepafinConstant.FAQ_UPDATED_SUCCESSFULLY))); + return ResponseEntity.status(HttpStatus.OK).body(new Response<>(response, Status.SUCCESS, Translator.toLocale(GepafinConstant.FAQ_UPDATED_SUCCESSFULLY))); } else { - return ResponseEntity.status(HttpStatus.NOT_FOUND) - .body(new Response<>(null, Status.NOT_FOUND, Translator.toLocale(GepafinConstant.FAQ_NOT_FOUND))); + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(new Response<>(null, Status.NOT_FOUND, Translator.toLocale(GepafinConstant.FAQ_NOT_FOUND))); } } @Override public ResponseEntity> deleteFaq(HttpServletRequest request, Long id) { + /** This code is responsible for creating user action logs for the "Delete FAQ" operation. **/ loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.DELETE).actionContext(UserActionContextEnum.DELETE_FAQ).build()); faqService.deleteFaq(request, id); - return ResponseEntity.status(HttpStatus.OK) - .body(new Response<>(null, Status.SUCCESS, Translator.toLocale(GepafinConstant.FAQ_DELETED_SUCCESSFULLY))); + return ResponseEntity.status(HttpStatus.OK).body(new Response<>(null, Status.SUCCESS, Translator.toLocale(GepafinConstant.FAQ_DELETED_SUCCESSFULLY))); } } diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/UserApiController.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/UserApiController.java index 0b170375..7ff12c2a 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/UserApiController.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/UserApiController.java @@ -216,14 +216,18 @@ public class UserApiController implements UserApi { } @Override - public ResponseEntity>> getAllUsers(HttpServletRequest request, - Long roleId) { + public ResponseEntity>> getAllUsers(HttpServletRequest request, Long roleId) { + log.info("Get all Users by Role ID - Role ID: {}", roleId); + + /** This code is responsible for creating user action logs for the "Get all users by role" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.VIEW).actionContext(UserActionContextEnum.GET_ALL_USERS_BY_ROLE).build()); + List users = userService.getAllUsers(request, roleId); - return ResponseEntity.status(HttpStatus.OK) - .body(new Response<>(users, Status.SUCCESS, Translator.toLocale(GepafinConstant.GET_USERS_SUCCESS_MSG))); + + return ResponseEntity.status(HttpStatus.OK).body(new Response<>(users, Status.SUCCESS, Translator.toLocale(GepafinConstant.GET_USERS_SUCCESS_MSG))); } - + @Override public void returnNoFavicon() { // Do nothing 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 8c3c0413..92fa7bec 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 @@ -1788,13 +1788,17 @@ - + + + - + + + From 281848208a883c23a8bc14179d1ff9d810ebf084 Mon Sep 17 00:00:00 2001 From: rajesh Date: Sat, 23 Nov 2024 22:56:17 +0530 Subject: [PATCH 13/43] Added audit for assigned application --- .../dao/AssignedApplicationsDao.java | 113 +++++++++++------- .../enums/UserActionContextEnum.java | 8 +- .../impl/AssignedApplicationsController.java | 26 +++- 3 files changed, 101 insertions(+), 46 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/AssignedApplicationsDao.java b/src/main/java/net/gepafin/tendermanagement/dao/AssignedApplicationsDao.java index b3e27da5..d796432f 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/AssignedApplicationsDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/AssignedApplicationsDao.java @@ -1,20 +1,26 @@ package net.gepafin.tendermanagement.dao; + import jakarta.persistence.criteria.Predicate; import jakarta.servlet.http.HttpServletRequest; import net.gepafin.tendermanagement.config.Translator; import net.gepafin.tendermanagement.constants.GepafinConstant; import net.gepafin.tendermanagement.entities.ApplicationEntity; import net.gepafin.tendermanagement.entities.AssignedApplicationsEntity; +import net.gepafin.tendermanagement.entities.FaqEntity; import net.gepafin.tendermanagement.entities.UserEntity; import net.gepafin.tendermanagement.enums.ApplicationStatusTypeEnum; import net.gepafin.tendermanagement.enums.AssignedApplicationEnum; +import net.gepafin.tendermanagement.enums.VersionActionTypeEnum; import net.gepafin.tendermanagement.model.request.AssignedApplicationsRequest; +import net.gepafin.tendermanagement.model.request.VersionHistoryRequest; import net.gepafin.tendermanagement.model.response.AssignedApplicationsResponse; import net.gepafin.tendermanagement.repositories.ApplicationRepository; import net.gepafin.tendermanagement.repositories.AssignedApplicationsRepository; import net.gepafin.tendermanagement.service.ApplicationService; import net.gepafin.tendermanagement.service.UserService; import net.gepafin.tendermanagement.util.DateTimeUtil; +import net.gepafin.tendermanagement.util.LoggingUtil; +import net.gepafin.tendermanagement.util.Utils; import net.gepafin.tendermanagement.util.Validator; import net.gepafin.tendermanagement.web.rest.api.errors.CustomValidationException; import net.gepafin.tendermanagement.web.rest.api.errors.ResourceNotFoundException; @@ -44,15 +50,20 @@ public class AssignedApplicationsDao { @Autowired private UserService userService; - + @Autowired private Validator validator; + @Autowired + private LoggingUtil loggingUtil; - public AssignedApplicationsResponse createAssignedApplications(Long applicationId, Long userId, UserEntity assignedByUser, AssignedApplicationsRequest assignedApplicationsRequest){ - log.info("Assigning application to pre-Instructor with details: {}", applicationId,userId); + @Autowired + private HttpServletRequest request; + + public AssignedApplicationsResponse createAssignedApplications(Long applicationId, Long userId, UserEntity assignedByUser, AssignedApplicationsRequest assignedApplicationsRequest) { + log.info("Assigning application to pre-Instructor with details: {}", applicationId, userId); AssignedApplicationsEntity assignedApplications = assignedApplicationsRepository.findByApplicationIdAndIsDeletedFalse(applicationId).orElse(null); - if(assignedApplications!=null){ + if (assignedApplications != null) { throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.APPLICATION_ALREADY_ASSIGNED)); } ApplicationEntity application = applicationService.validateApplication(applicationId); @@ -64,8 +75,13 @@ public class AssignedApplicationsDao { Translator.toLocale(GepafinConstant.INVALID_APPLICATION_STATUS) ); } + ApplicationEntity oldApplicationEntity = Utils.getClonedEntityForData(application); application.setStatus(ApplicationStatusTypeEnum.EVALUATION.getValue()); applicationRepository.save(application); + + /** This code is responsible for adding a version history log for the "Create Application" operation. **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplicationEntity).newData(application).build()); + UserEntity user = userService.validateUser(userId); AssignedApplicationsEntity assignment = createAssignmentEntity(application, user.getId(), assignedByUser, assignedApplicationsRequest); AssignedApplicationsResponse assignApplicationToInstructorResponse = convertEntityToResponse(assignment); @@ -74,28 +90,34 @@ public class AssignedApplicationsDao { return assignApplicationToInstructorResponse; } - public AssignedApplicationsEntity createAssignmentEntity(ApplicationEntity application, Long userId, UserEntity assignedByUser, AssignedApplicationsRequest assignedApplicationsRequest){ - AssignedApplicationsEntity assignApplication= new AssignedApplicationsEntity(); + public AssignedApplicationsEntity createAssignmentEntity(ApplicationEntity application, Long userId, UserEntity assignedByUser, AssignedApplicationsRequest assignedApplicationsRequest) { + AssignedApplicationsEntity assignApplication = new AssignedApplicationsEntity(); assignApplication.setApplication(application); assignApplication.setAssignedBy(assignedByUser.getId()); assignApplication.setUserId(userId); assignApplication.setStatus(AssignedApplicationEnum.OPEN.getValue()); - if(assignedApplicationsRequest.getStatus() != null) { - assignApplication.setStatus(assignedApplicationsRequest.getStatus().getValue()); + if (assignedApplicationsRequest.getStatus() != null) { + assignApplication.setStatus(assignedApplicationsRequest.getStatus().getValue()); } assignApplication.setNote(assignedApplicationsRequest.getNote()); assignApplication.setIsDeleted(false); assignApplication.setAssignedAt(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); - AssignedApplicationsEntity assignedApplicationsEntity = saveAssignedApplication(assignApplication); + + AssignedApplicationsEntity assignedApplicationsEntity = saveAssignedApplication(assignApplication, null, VersionActionTypeEnum.INSERT); return assignedApplicationsEntity; } - public AssignedApplicationsEntity saveAssignedApplication(AssignedApplicationsEntity assignedApplicationsEntity){ - AssignedApplicationsEntity assignedApplication= assignedApplicationsRepository.save(assignedApplicationsEntity); + + public AssignedApplicationsEntity saveAssignedApplication(AssignedApplicationsEntity assignedApplicationsEntity, AssignedApplicationsEntity oldAssignedApplicationEntity, VersionActionTypeEnum actionTypeEnum) { + AssignedApplicationsEntity assignedApplication = assignedApplicationsRepository.save(assignedApplicationsEntity); + + /** This code is responsible for adding a version history log for the "Create Application" operation. **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(actionTypeEnum).oldData(oldAssignedApplicationEntity).newData(assignedApplication).build()); + return assignedApplication; } - public AssignedApplicationsResponse convertEntityToResponse(AssignedApplicationsEntity assignedApplications){ + public AssignedApplicationsResponse convertEntityToResponse(AssignedApplicationsEntity assignedApplications) { AssignedApplicationsResponse assignedApplicationsResponse = new AssignedApplicationsResponse(); assignedApplicationsResponse.setId(assignedApplications.getId()); assignedApplicationsResponse.setApplicationId(assignedApplications.getApplication().getId()); @@ -136,60 +158,65 @@ public class AssignedApplicationsDao { return assignedApplicationsResponse; } - public AssignedApplicationsEntity validateAssignedApplication(Long id){ - AssignedApplicationsEntity assignedApplication = assignedApplicationsRepository.findByIdAndIsDeletedFalse(id).orElseThrow(()-> - new ResourceNotFoundException(Status.NOT_FOUND,Translator.toLocale(GepafinConstant.ASSIGNED_APPLICATION_NOT_FOUND_MSG))); - return assignedApplication; + public AssignedApplicationsEntity validateAssignedApplication(Long id) { + AssignedApplicationsEntity assignedApplication = assignedApplicationsRepository.findByIdAndIsDeletedFalse(id).orElseThrow(() -> + new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.ASSIGNED_APPLICATION_NOT_FOUND_MSG))); + return assignedApplication; } public void deleteById(HttpServletRequest request, Long id) { log.info("Deleting assigned application with ID: {}", id); - AssignedApplicationsEntity assignedApplicationsEntity= validateAssignedApplication(id); + AssignedApplicationsEntity assignedApplicationsEntity = validateAssignedApplication(id); validator.validatePreInstructor(request, assignedApplicationsEntity.getUserId()); + AssignedApplicationsEntity oldAssignedApplicationEntity = Utils.getClonedEntityForData(assignedApplicationsEntity); assignedApplicationsEntity.setIsDeleted(true); - assignedApplicationsEntity= saveAssignedApplication(assignedApplicationsEntity); + assignedApplicationsEntity = saveAssignedApplication(assignedApplicationsEntity, oldAssignedApplicationEntity, VersionActionTypeEnum.DELETE); log.info("Assigned Application deleted with ID: {}", id); } - public List getAllAssignedApplications(HttpServletRequest request, Long userId) { - UserEntity user = validator.validateUser(request); - if(validator.checkIsPreInstructor() && userId == null) { - throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.USER_ID_NOT_NULL_MSG)); - } - if(userId != null) { - validator.validatePreInstructor(request, userId); - } - Specification spec = search(user.getHub().getId() ,userId); - List assignedApplicationsEntityList = assignedApplicationsRepository.findAll(spec); - return assignedApplicationsEntityList.stream() - .map(entity -> convertEntityToResponse(entity)) - .collect(Collectors.toList()); + public List getAllAssignedApplications(HttpServletRequest request, Long userId) { + UserEntity user = validator.validateUser(request); + if (validator.checkIsPreInstructor() && userId == null) { + throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.USER_ID_NOT_NULL_MSG)); } - private Specification search(Long hubId, Long userId) { - return (root, query, builder) -> { - Predicate predicate = builder.isFalse(root.get("isDeleted")); - if (userId != null) { - predicate = builder.and(predicate, builder.equal(root.get("userId"), userId)); - } - predicate = builder.and(predicate, builder.equal(root.get("application").get("hubId"), hubId)); - return predicate; - }; + if (userId != null) { + validator.validatePreInstructor(request, userId); } + Specification spec = search(user.getHub().getId(), userId); + List assignedApplicationsEntityList = assignedApplicationsRepository.findAll(spec); + return assignedApplicationsEntityList.stream() + .map(entity -> convertEntityToResponse(entity)) + .collect(Collectors.toList()); + } + + private Specification search(Long hubId, Long userId) { + return (root, query, builder) -> { + Predicate predicate = builder.isFalse(root.get("isDeleted")); + if (userId != null) { + predicate = builder.and(predicate, builder.equal(root.get("userId"), userId)); + } + predicate = builder.and(predicate, builder.equal(root.get("application").get("hubId"), hubId)); + return predicate; + }; + } public AssignedApplicationsResponse updateAssignedApplication(HttpServletRequest request, - Long id, AssignedApplicationsRequest updateRequest) { - UserEntity updatedByUser = validator.validateUser(request); + Long id, AssignedApplicationsRequest updateRequest) { + UserEntity updatedByUser = validator.validateUser(request); log.info("Updating assigned application with ID: {}", id); AssignedApplicationsEntity existingAssignment = validateAssignedApplication(id); validator.validatePreInstructor(request, existingAssignment.getUserId()); + + AssignedApplicationsEntity oldAssignedApplicationEntity = Utils.getClonedEntityForData(existingAssignment); + setIfUpdated(existingAssignment::getNote, existingAssignment::setNote, updateRequest.getNote()); setIfUpdated(existingAssignment::getStatus, existingAssignment::setStatus, updateRequest.getStatus().name()); setIfUpdated(existingAssignment::getAssignedBy, existingAssignment::setAssignedBy, updatedByUser.getId()); existingAssignment.setUpdatedDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); - AssignedApplicationsEntity updatedAssignment = saveAssignedApplication(existingAssignment); + AssignedApplicationsEntity updatedAssignment = saveAssignedApplication(existingAssignment, oldAssignedApplicationEntity, VersionActionTypeEnum.UPDATE); AssignedApplicationsResponse response = convertEntityToResponse(updatedAssignment); log.info("Assigned application updated successfully: {}", response); return response; diff --git a/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java index 538a60a3..e199dc90 100644 --- a/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java +++ b/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java @@ -29,7 +29,13 @@ public enum UserActionContextEnum { CREATE_FAQ("CREATE_FAQ"), GET_FAQ("GET_FAQ"), UPDATE_FAQ_DETAILS("UPDATE_FAQ_DETAILS"), - DELETE_FAQ("DELETE_FAQ") + DELETE_FAQ("DELETE_FAQ"), + + /** Assigned Application action context **/ + CREATE_ASSIGNED_APPLICATION("CREATE_ASSIGNED_APPLICATION"), + DELETE_ASSIGNED_APPLICATION("DELETE_ASSIGNED_APPLICATION"), + GET_ASSIGNED_APPLICATION("GET_ASSIGNED_APPLICATION"), + UPDATE_ASSIGNED_APPLICATION_DETAILS("UPDATE_ASSIGNED_APPLICATION_DETAILS") ; private final String value; diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/AssignedApplicationsController.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/AssignedApplicationsController.java index 90f989de..7f22337a 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/AssignedApplicationsController.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/AssignedApplicationsController.java @@ -4,10 +4,14 @@ import jakarta.servlet.http.HttpServletRequest; import lombok.extern.log4j.Log4j2; 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.AssignedApplicationsRequest; +import net.gepafin.tendermanagement.model.request.UserActionRequest; import net.gepafin.tendermanagement.model.response.AssignedApplicationsResponse; import net.gepafin.tendermanagement.model.util.Response; import net.gepafin.tendermanagement.service.AssignedApplicationsService; +import net.gepafin.tendermanagement.util.LoggingUtil; import net.gepafin.tendermanagement.web.rest.api.AssignedApplicationsApi; import net.gepafin.tendermanagement.web.rest.api.errors.Status; import org.springframework.beans.factory.annotation.Autowired; @@ -25,11 +29,16 @@ public class AssignedApplicationsController implements AssignedApplicationsApi { @Autowired AssignedApplicationsService assignedApplicationsService; + @Autowired + private LoggingUtil loggingUtil; @Override public ResponseEntity> createAssignedApplications(HttpServletRequest request, Long applicationId, Long userId, AssignedApplicationsRequest assignedApplicationsRequest) { log.info("Assigning Application To PreInstructor"); - AssignedApplicationsResponse responseData = assignedApplicationsService.createAssignedApplications(request,applicationId,userId, assignedApplicationsRequest); + /** This code is responsible for creating user action logs for the "Create Assigned Applications" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.INSERT) + .actionContext(UserActionContextEnum.CREATE_ASSIGNED_APPLICATION).build()); + AssignedApplicationsResponse responseData = assignedApplicationsService.createAssignedApplications(request, applicationId, userId, assignedApplicationsRequest); return ResponseEntity.status(HttpStatus.CREATED) .body(new Response<>(responseData, Status.SUCCESS, Translator.toLocale(GepafinConstant.APPLICATION_ASSIGNED))); } @@ -37,7 +46,10 @@ public class AssignedApplicationsController implements AssignedApplicationsApi { @Override public ResponseEntity> deleteAssignedApplication(HttpServletRequest request, Long id) { log.info("Delete Assigned Application - Assigned Application ID: {}", id); - assignedApplicationsService.deleteApplication(request,id); + /** This code is responsible for creating user action logs for the "Delete Assigned Applications" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.DELETE).actionContext(UserActionContextEnum.DELETE_ASSIGNED_APPLICATION).build()); + + assignedApplicationsService.deleteApplication(request, id); return ResponseEntity.status(HttpStatus.OK) .body(new Response<>(null, Status.SUCCESS, Translator.toLocale(GepafinConstant.DELETE_ASSIGNED_APPLICATION_SUCCESS_MSG))); } @@ -45,6 +57,9 @@ public class AssignedApplicationsController implements AssignedApplicationsApi { @Override public ResponseEntity>> getAllAssignedApplications(HttpServletRequest request, Long userId) { log.info("Get All Assigned Applications"); + /** This code is responsible for creating user action logs for the "get Assigned Applications" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.VIEW) + .actionContext(UserActionContextEnum.GET_ASSIGNED_APPLICATION).build()); List applications = assignedApplicationsService.getAllAssignedApplications(request, userId); return ResponseEntity.status(HttpStatus.OK) .body(new Response<>(applications, Status.SUCCESS, Translator.toLocale(GepafinConstant.GET_ASSIGNED_APPLICATION_SUCCESS_MSG))); @@ -53,6 +68,9 @@ public class AssignedApplicationsController implements AssignedApplicationsApi { @Override public ResponseEntity> updateAssignedApplication(HttpServletRequest request, Long id, AssignedApplicationsRequest updateAssignedApplicationRequest) { log.info("Update Assigned Application"); + /** This code is responsible for "Updating Assigned Applications details" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.UPDATE) + .actionContext(UserActionContextEnum.UPDATE_ASSIGNED_APPLICATION_DETAILS).build()); AssignedApplicationsResponse updateAssignedApplication = assignedApplicationsService.updateAssignedApplication(request, id, updateAssignedApplicationRequest); return ResponseEntity.status(HttpStatus.CREATED) .body(new Response<>(updateAssignedApplication, Status.SUCCESS, Translator.toLocale(GepafinConstant.ASSIGNED_APPLICATION_UPDATE_SUCCESSFULLY_MSG))); @@ -61,6 +79,10 @@ public class AssignedApplicationsController implements AssignedApplicationsApi { @Override public ResponseEntity> getAssignedApplicationById(HttpServletRequest request, Long id) { log.info("Get Assigned Applications By Id"); + + /** This code is responsible for creating user action logs for the "get Assigned Applications by id" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.VIEW) + .actionContext(UserActionContextEnum.GET_ASSIGNED_APPLICATION).build()); AssignedApplicationsResponse application = assignedApplicationsService.getAssignedApplicationById(request, id); return ResponseEntity.status(HttpStatus.OK) .body(new Response<>(application, Status.SUCCESS, Translator.toLocale(GepafinConstant.GET_ASSIGNED_APPLICATION_SUCCESS_MSG))); From bd18f488021500c4fa0e0258bea19fd53a87c253 Mon Sep 17 00:00:00 2001 From: rajesh Date: Sun, 24 Nov 2024 14:17:57 +0530 Subject: [PATCH 14/43] Added audit for Application Evaluation --- .../dao/ApplicationEvaluationDao.java | 123 ++++++++++++------ .../enums/UserActionContextEnum.java | 5 + .../ApplicationEvaluationApiController.java | 28 +++- 3 files changed, 114 insertions(+), 42 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java index 2bcbade9..d6f598b0 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java @@ -4,19 +4,18 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; +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.*; -import net.gepafin.tendermanagement.model.request.ApplicationEvaluationRequest; -import net.gepafin.tendermanagement.model.request.ChecklistRequest; -import net.gepafin.tendermanagement.model.request.CriteriaRequest; -import net.gepafin.tendermanagement.model.request.FieldRequest; +import net.gepafin.tendermanagement.model.request.*; import net.gepafin.tendermanagement.model.response.*; import net.gepafin.tendermanagement.repositories.*; import net.gepafin.tendermanagement.service.ApplicationService; import net.gepafin.tendermanagement.service.CallService; import net.gepafin.tendermanagement.service.UserService; +import net.gepafin.tendermanagement.util.LoggingUtil; import net.gepafin.tendermanagement.util.Utils; import net.gepafin.tendermanagement.web.rest.api.errors.ResourceNotFoundException; import net.gepafin.tendermanagement.web.rest.api.errors.Status; @@ -78,10 +77,16 @@ public class ApplicationEvaluationDao { @Autowired ApplicationAmendmentRequestRepository applicationAmendmentRequestRepository; - + @Autowired private FormDao formDao; + @Autowired + private LoggingUtil loggingUtil; + + @Autowired + private HttpServletRequest request; + private ApplicationEvaluationEntity convertToEntity(UserEntity user, ApplicationEvaluationRequest req, Long assignedApplciationId) { ApplicationEvaluationEntity entity = new ApplicationEvaluationEntity(); @@ -132,7 +137,6 @@ public class ApplicationEvaluationDao { } - private void setCriteriaResponses(ApplicationEvaluationEntity entity, ApplicationEvaluationResponse response, List evaluationCriterias) { List criteriaResponsesFromEntity = entity.getCriteria() != null ? @@ -326,7 +330,7 @@ public class ApplicationEvaluationDao { FormEntity formEntity = applicationForm.getForm(); if (formEntity != null) { // List contentResponseBeans = Utils.convertJsonStringToList(formEntity.getContent(), ContentResponseBean.class); - List contentResponseBeans = formDao.convertFormEntityToFormResponseBean(formEntity).getContent(); + List contentResponseBeans = formDao.convertFormEntityToFormResponseBean(formEntity).getContent(); contentResponseBeans.forEach(contentResponseBean -> { if ("fileupload".equals(contentResponseBean.getName()) && contentResponseBean.getId().equals(fieldResponse.getId())) { String label = null; @@ -342,7 +346,7 @@ public class ApplicationEvaluationDao { Optional optionalFormField = applicationFormFieldRepository.findByFieldIdAndApplicationFormIdAndApplicationFormApplicationId( - fieldResponse.getId(), applicationForm.getId(), entity.getApplicationId()); + fieldResponse.getId(), applicationForm.getId(), entity.getApplicationId()); if (optionalFormField.isPresent()) { ApplicationFormFieldEntity formField = optionalFormField.get(); @@ -403,7 +407,7 @@ public class ApplicationEvaluationDao { response.setBeneficiary(beneficiary); response.setMinScore(call.getThreshold() != null ? call.getThreshold() : null); response.setCallName(application.getCall().getName() != null ? application.getCall().getName() : null); - response.setProtocolNumber(application.getProtocol() != null ? application.getProtocol().getProtocolNumber() : null); + response.setProtocolNumber((application.getProtocol() != null && application.getProtocol().getProtocolNumber() != null) ? application.getProtocol().getProtocolNumber() : null); response.setSubmissionDate(application.getSubmissionDate() != null ? application.getSubmissionDate() : null); response.setEvaluationDate(application.getSubmissionDate() != null ? application.getSubmissionDate().plusDays(30) : null); LocalDateTime callEndDate = application.getCall().getEndDate(); @@ -418,23 +422,31 @@ public class ApplicationEvaluationDao { Optional existingEntityOptional = applicationEvaluationRepository.findByAssignedApplicationsEntity_IdAndIsDeletedFalse(assignedApplicationId); - ApplicationEvaluationEntity entity; + ApplicationEvaluationEntity entity = null; Optional assignedApplications = assignedApplicationsRepository.findByIdAndIsDeletedFalse(assignedApplicationId); - + ApplicationEvaluationEntity oldApplicationEvaluation = null; + VersionActionTypeEnum actionType = VersionActionTypeEnum.INSERT; if (existingEntityOptional.isPresent()) { entity = existingEntityOptional.get(); + oldApplicationEvaluation = Utils.getClonedEntityForData(entity); entity.setCriteria(Utils.convertObjectToJson(filterNonNullCriteria(processCriteria(entity, req)))); entity.setChecklist(Utils.convertObjectToJson(filterNonNullChecklist(processChecklist(entity, req)))); entity.setFile(Utils.convertObjectToJson(filterNonNullFields(processField(entity, req)))); entity.setIsDeleted(false); setIfUpdated(entity::getNote, entity::setNote, req.getNote()); + actionType = VersionActionTypeEnum.UPDATE; } else { entity = convertToEntity(user, req, assignedApplicationId); + actionType = VersionActionTypeEnum.INSERT; } ApplicationStatusForEvaluation status = req.getApplicationStatus(); ApplicationEvaluationEntity savedEntity = applicationEvaluationRepository.save(entity); + + /** This code is responsible for adding a version history log for the "Update Application Evaluation" operation. **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(actionType).oldData(oldApplicationEvaluation).newData(entity).build()); + if (status != null) { ApplicationEntity application = applicationService.validateApplication(assignedApplications.get().getApplication().getId()); AssignedApplicationsEntity assignedApplicationsEntity = assignedApplications.get(); @@ -692,10 +704,10 @@ public class ApplicationEvaluationDao { String formFieldId = criteriaFormField.getFormFieldId(); if (!mappedFieldMap.containsKey(formFieldId)) { // CriteriaMappedField mappedField = new CriteriaMappedField(); - CriteriaMappedField mappedField = populateMappedField(formFieldId, criteriaFormField, applicationForm, applicationId); + CriteriaMappedField mappedField = populateMappedField(formFieldId, criteriaFormField, applicationForm, applicationId); if(mappedField != null) { - mappedFieldMap.put(formFieldId, mappedField); - } + mappedFieldMap.put(formFieldId, mappedField); + } } } } @@ -704,16 +716,16 @@ public class ApplicationEvaluationDao { } private CriteriaMappedField populateMappedField(String formFieldId, - CriteriaFormFieldEntity criteriaFormField, - ApplicationFormEntity applicationForm, Long applicationId) { - CriteriaMappedField mappedField = new CriteriaMappedField(); + CriteriaFormFieldEntity criteriaFormField, + ApplicationFormEntity applicationForm, Long applicationId) { + CriteriaMappedField mappedField = new CriteriaMappedField(); mappedField.setId(formFieldId); if(Boolean.FALSE.equals(criteriaFormField.getFormId().equals(applicationForm.getForm().getId()))) { - return null; + return null; } formRepository.findById(criteriaFormField.getFormId()).ifPresent(formEntity -> { // List contentResponseBeans = Utils.convertJsonStringToList(formEntity.getContent(), ContentResponseBean.class); - List contentResponseBeans = formDao.convertFormEntityToFormResponseBean(formEntity).getContent(); + List contentResponseBeans = formDao.convertFormEntityToFormResponseBean(formEntity).getContent(); contentResponseBeans.stream().filter(bean -> bean.getId().equals(formFieldId)).findFirst().ifPresent(contentResponseBean -> { String label = getLabel(contentResponseBean); mappedField.setFieldName(contentResponseBean.getName()); @@ -832,7 +844,7 @@ public class ApplicationEvaluationDao { } private void setChecklistResponses(ApplicationEvaluationEntity entity, Long applicationId, ApplicationEvaluationResponse response, - List checklistEntities) { + List checklistEntities) { List checklistResponses = entity.getChecklist() != null ? Utils.convertJsonToList(entity.getChecklist(), new TypeReference>() { }) : getChecklistResponse(applicationId); @@ -850,7 +862,7 @@ public class ApplicationEvaluationDao { } private void setFileResponses(ApplicationEvaluationEntity entity, Long applicationId, ApplicationEvaluationResponse response, - List applicationFormEntities) { + List applicationFormEntities) { List fieldResponses = entity.getFile() != null ? Utils.convertJsonToList(entity.getFile(), new TypeReference>() { }) : getFieldResponses(applicationId); @@ -865,7 +877,7 @@ public class ApplicationEvaluationDao { FormEntity formEntity = applicationForm.getForm(); if (formEntity != null) { // List contentResponseBeans = Utils.convertJsonStringToList(formEntity.getContent(), ContentResponseBean.class); - List contentResponseBeans = formDao.convertFormEntityToFormResponseBean(formEntity).getContent(); + List contentResponseBeans = formDao.convertFormEntityToFormResponseBean(formEntity).getContent(); contentResponseBeans.forEach(contentResponseBean -> { if ("fileupload".equals(contentResponseBean.getName()) && contentResponseBean.getId().equals(fieldResponse.getId())) { String label = null; @@ -881,7 +893,7 @@ public class ApplicationEvaluationDao { Optional optionalFormField = applicationFormFieldRepository.findByFieldIdAndApplicationFormIdAndApplicationFormApplicationId( - fieldResponse.getId(), applicationForm.getId(), applicationId); + fieldResponse.getId(), applicationForm.getId(), applicationId); if (optionalFormField.isPresent() && optionalFormField.get().getFieldValue() != null) { String[] documentIds = optionalFormField.get().getFieldValue().split(","); @@ -926,7 +938,7 @@ public class ApplicationEvaluationDao { response.setBeneficiary(beneficiary); response.setCallName(application.getCall().getName() != null ? application.getCall().getName() : null); - response.setProtocolNumber(application.getProtocol() != null ? application.getProtocol().getProtocolNumber() : null); + response.setProtocolNumber((application.getProtocol() != null && application.getProtocol().getProtocolNumber() != null) ? application.getProtocol().getProtocolNumber() : null); response.setSubmissionDate(application.getSubmissionDate() != null ? application.getSubmissionDate() : null); response.setEvaluationDate(application.getSubmissionDate() != null ? application.getSubmissionDate().plusDays(30) : null); @@ -998,7 +1010,7 @@ public class ApplicationEvaluationDao { FormEntity formEntity = formRepository.findById(criteriaFormField.getFormId()).orElse(null); if (formEntity != null) { // List contentResponseBeans = Utils.convertJsonStringToList(formEntity.getContent(), ContentResponseBean.class); - List contentResponseBeans = formDao.convertFormEntityToFormResponseBean(formEntity).getContent(); + List contentResponseBeans = formDao.convertFormEntityToFormResponseBean(formEntity).getContent(); contentResponseBeans.stream() .filter(bean -> bean.getId().equals(criteriaFormField.getFormFieldId())) .findFirst() @@ -1083,15 +1095,15 @@ public class ApplicationEvaluationDao { private void handleParagraphField(Long applicationId, CriteriaFormFieldEntity criteriaFormField, ContentResponseBean contentResponseBean, CriteriaMappedField mappedField) { findFormFieldValue(applicationId, criteriaFormField.getFormFieldId()).ifPresent(formField -> { - String paragraph = contentResponseBean.getSettings().stream() - .filter(setting -> "text".equals(setting.getName())) - .map(SettingResponseBean::getValue) - .map(Object::toString) - .findFirst() - .orElse(null); - if (paragraph != null) { - mappedField.setFieldValue(paragraph.trim()); - } + String paragraph = contentResponseBean.getSettings().stream() + .filter(setting -> "text".equals(setting.getName())) + .map(SettingResponseBean::getValue) + .map(Object::toString) + .findFirst() + .orElse(null); + if (paragraph != null) { + mappedField.setFieldValue(paragraph.trim()); + } }); } @@ -1276,17 +1288,25 @@ public class ApplicationEvaluationDao { public void deleteById(Long id) { ApplicationEvaluationEntity applicationEvaluationEntity = validateApplicationEvaluation(id); + ApplicationEvaluationEntity oldApplicationEvaluation = Utils.getClonedEntityForData(applicationEvaluationEntity); applicationEvaluationEntity.setIsDeleted(true); - saveApplicationEvaluationEntity(applicationEvaluationEntity); + saveApplicationEvaluationEntity(applicationEvaluationEntity, oldApplicationEvaluation); } - public ApplicationEvaluationEntity saveApplicationEvaluationEntity(ApplicationEvaluationEntity applicationEvaluationEntityData) { + public ApplicationEvaluationEntity saveApplicationEvaluationEntity(ApplicationEvaluationEntity applicationEvaluationEntityData, ApplicationEvaluationEntity oldApplicationEvaluation) { - return applicationEvaluationRepository.save(applicationEvaluationEntityData); + ApplicationEvaluationEntity applicationEvaluationEntity = applicationEvaluationRepository.save(applicationEvaluationEntityData); + + /** This code is responsible for adding a version history log for the "Delete Application Evaluation" operation. **/ + loggingUtil.addVersionHistory( + VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.DELETE).oldData(oldApplicationEvaluation).newData(applicationEvaluationEntityData) + .build()); + + return applicationEvaluationEntity; } public ApplicationEvaluationResponse updateApplicationEvaluationStatus(ApplicationEntity application, AssignedApplicationsEntity assignedApplicationsEntity, - ApplicationStatusForEvaluation newStatus) { + ApplicationStatusForEvaluation newStatus) { Optional existingEntityOptional = applicationEvaluationRepository.findByAssignedApplicationsEntity_IdAndIsDeletedFalse( assignedApplicationsEntity.getId()); @@ -1297,8 +1317,16 @@ public class ApplicationEvaluationDao { ApplicationEvaluationEntity existingEntity = existingEntityOptional.get(); // UserEntity userEntity = userService.validateUser(application.getUserId()); // callService.validatePublishedCall(application.getCall().getId(), userEntity.getHub().getId()); + ApplicationEntity oldApplicationEntity = Utils.getClonedEntityForData(application); application.setStatus(newStatus.getValue()); application = applicationRepository.save(application); + + /** This code is responsible for adding a version history log for the "Update Application" operation. **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplicationEntity).newData(application).build()); + + ApplicationEvaluationEntity oldApplicationEvaluation = Utils.getClonedEntityForData(existingEntity); + AssignedApplicationsEntity oldAssignedApplication = Utils.getClonedEntityForData(assignedApplicationsEntity); + String statusType = application.getStatus(); if (application.getStatus().equals(ApplicationStatusTypeEnum.APPROVED.getValue()) || application.getStatus().equals(ApplicationStatusTypeEnum.REJECTED.getValue())) { existingEntity.setStatus(ApplicationEvaluationStatusTypeEnum.CLOSE.getValue()); @@ -1307,9 +1335,24 @@ public class ApplicationEvaluationDao { entity = applicationEvaluationRepository.save(existingEntity); assignedApplicationsRepository.save(assignedApplicationsEntity); + if (application.getStatus().equals(ApplicationStatusTypeEnum.APPROVED.getValue()) || application.getStatus().equals(ApplicationStatusTypeEnum.REJECTED.getValue())) { + + /** This code is responsible for adding a version history log for the "Update Application Evaluation" operation. **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplicationEvaluation).newData(entity).build()); + + /** This code is responsible for adding a version history log for the "Update Assigned Application" operation. **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldAssignedApplication).newData(assignedApplicationsEntity).build()); + } + + List amendmentRequest = applicationAmendmentRequestRepository.findAllByApplicationEvaluationIdAndIsDeletedFalse(entity.getId()); - for (ApplicationAmendmentRequestEntity request : amendmentRequest) { - request.setStatus(ApplicationAmendmentRequestEnum.CLOSE.getValue()); + for (ApplicationAmendmentRequestEntity amendment : amendmentRequest) { + ApplicationAmendmentRequestEntity oldAmendment = Utils.getClonedEntityForData(amendment); + amendment.setStatus(ApplicationAmendmentRequestEnum.CLOSE.getValue()); + + /** This code is responsible for adding a version history log for the "Update Application Amendment" operation. **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldAmendment).newData(amendment).build()); + } applicationAmendmentRequestRepository.saveAll(amendmentRequest); if (Boolean.TRUE.equals(statusType.equals((ApplicationStatusTypeEnum.APPROVED.getValue())))) { diff --git a/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java index b9be7dfa..af692922 100644 --- a/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java +++ b/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java @@ -45,6 +45,11 @@ public enum UserActionContextEnum { UPDATE_FAQ_DETAILS("UPDATE_FAQ_DETAILS"), DELETE_FAQ("DELETE_FAQ"), + /** Application Evaluation action context **/ + CREATE_UPDATE_APPLICATION_EVALUATION("CREATE_UPDATE_APPLICATION_EVALUATION"), + GET_APPLICATION_EVALUATION("GET_APPLICATION_EVALUATION"), + DELETE_APPLICATION_EVALUATION("DELETE_APPLICATION_EVALUATION"), + /** Assigned Application action context **/ CREATE_ASSIGNED_APPLICATION("CREATE_ASSIGNED_APPLICATION"), DELETE_ASSIGNED_APPLICATION("DELETE_ASSIGNED_APPLICATION"), diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/ApplicationEvaluationApiController.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/ApplicationEvaluationApiController.java index f56a85fb..be177bf9 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/ApplicationEvaluationApiController.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/ApplicationEvaluationApiController.java @@ -4,10 +4,14 @@ import jakarta.servlet.http.HttpServletRequest; import net.gepafin.tendermanagement.config.Translator; import net.gepafin.tendermanagement.constants.GepafinConstant; import net.gepafin.tendermanagement.enums.ApplicationStatusForEvaluation; +import net.gepafin.tendermanagement.enums.UserActionContextEnum; +import net.gepafin.tendermanagement.enums.UserActionLogsEnum; import net.gepafin.tendermanagement.model.request.ApplicationEvaluationRequest; +import net.gepafin.tendermanagement.model.request.UserActionRequest; import net.gepafin.tendermanagement.model.response.ApplicationEvaluationResponse; import net.gepafin.tendermanagement.model.util.Response; import net.gepafin.tendermanagement.service.ApplicationEvaluationService; +import net.gepafin.tendermanagement.util.LoggingUtil; import net.gepafin.tendermanagement.web.rest.api.ApplicationEvaluationApi; import net.gepafin.tendermanagement.web.rest.api.errors.Status; import org.springframework.beans.factory.annotation.Autowired; @@ -23,12 +27,20 @@ public class ApplicationEvaluationApiController implements ApplicationEvaluation @Autowired private ApplicationEvaluationService applicationEvaluationService; + @Autowired + private LoggingUtil loggingUtil; + @Override public ResponseEntity> createOrUpdateApplicationEvaluation( HttpServletRequest request, Long assignedApplicationsId, ApplicationEvaluationRequest evaluationRequest) { + /** This code is responsible for creating user action logs for the "Create or update Application Evaluation" operation. **/ + loggingUtil.logUserAction( + UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.UPDATE).actionContext(UserActionContextEnum.CREATE_UPDATE_APPLICATION_EVALUATION).build()); + + ApplicationEvaluationResponse response = applicationEvaluationService.createOrUpdateApplicationEvaluation( request, evaluationRequest, assignedApplicationsId); @@ -41,6 +53,11 @@ public class ApplicationEvaluationApiController implements ApplicationEvaluation public ResponseEntity> getApplicationEvaluationByApplicationId( HttpServletRequest request, Long applicationId, Long assignedApplicationId) { + + /** This code is responsible for creating user action logs for the "Get Application Evaluation" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.VIEW).actionContext(UserActionContextEnum.GET_APPLICATION_EVALUATION).build()); + + ApplicationEvaluationResponse response = null; response = applicationEvaluationService.getApplicationEvaluationByApplicationId(request, applicationId,assignedApplicationId); return ResponseEntity.status(HttpStatus.OK) @@ -50,8 +67,15 @@ public class ApplicationEvaluationApiController implements ApplicationEvaluation @Override public ResponseEntity> deleteApplicationEvaluation(HttpServletRequest request, - Long id) { - applicationEvaluationService.deleteApplicationEvaluation(request,id); + Long id) { + + + /** This code is responsible for creating user action logs for the "Delete Application Evaluation" operation. **/ + loggingUtil.logUserAction( + UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.DELETE).actionContext(UserActionContextEnum.DELETE_APPLICATION_EVALUATION).build()); + + + applicationEvaluationService.deleteApplicationEvaluation(request, id); return ResponseEntity.status(HttpStatus.OK) .body(new Response<>(null, Status.SUCCESS, Translator.toLocale(GepafinConstant.EVALUATION_DELETED_SUCCESSFULLY))); } From ee7a958a084cfd348532c029e7493f7ad2a0fc88 Mon Sep 17 00:00:00 2001 From: rajesh Date: Sun, 24 Nov 2024 14:37:16 +0530 Subject: [PATCH 15/43] Updated code --- .../tendermanagement/dao/ApplicationEvaluationDao.java | 2 +- .../gepafin/tendermanagement/dao/AssignedApplicationsDao.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java index d6f598b0..7a199fd7 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java @@ -1299,7 +1299,7 @@ public class ApplicationEvaluationDao { /** This code is responsible for adding a version history log for the "Delete Application Evaluation" operation. **/ loggingUtil.addVersionHistory( - VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.DELETE).oldData(oldApplicationEvaluation).newData(applicationEvaluationEntityData) + VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.SOFT_DELETE).oldData(oldApplicationEvaluation).newData(applicationEvaluationEntityData) .build()); return applicationEvaluationEntity; diff --git a/src/main/java/net/gepafin/tendermanagement/dao/AssignedApplicationsDao.java b/src/main/java/net/gepafin/tendermanagement/dao/AssignedApplicationsDao.java index d796432f..cbf1f097 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/AssignedApplicationsDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/AssignedApplicationsDao.java @@ -79,7 +79,7 @@ public class AssignedApplicationsDao { application.setStatus(ApplicationStatusTypeEnum.EVALUATION.getValue()); applicationRepository.save(application); - /** This code is responsible for adding a version history log for the "Create Application" operation. **/ + /** This code is responsible for adding a version history log for the "Update Application" operation. **/ loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplicationEntity).newData(application).build()); UserEntity user = userService.validateUser(userId); @@ -170,7 +170,7 @@ public class AssignedApplicationsDao { validator.validatePreInstructor(request, assignedApplicationsEntity.getUserId()); AssignedApplicationsEntity oldAssignedApplicationEntity = Utils.getClonedEntityForData(assignedApplicationsEntity); assignedApplicationsEntity.setIsDeleted(true); - assignedApplicationsEntity = saveAssignedApplication(assignedApplicationsEntity, oldAssignedApplicationEntity, VersionActionTypeEnum.DELETE); + assignedApplicationsEntity = saveAssignedApplication(assignedApplicationsEntity, oldAssignedApplicationEntity, VersionActionTypeEnum.SOFT_DELETE); log.info("Assigned Application deleted with ID: {}", id); } From 85e4efd0dd7a5d8998641515a8c331c11a71d513 Mon Sep 17 00:00:00 2001 From: rajesh Date: Sun, 24 Nov 2024 16:24:14 +0530 Subject: [PATCH 16/43] Added audit for Beneficiary Preferred Call --- .../dao/BeneficiaryPreferredCallDao.java | 29 +++++++++++++++-- .../enums/UserActionContextEnum.java | 6 ++++ ...BeneficiaryPreferredCallApiController.java | 31 ++++++++++++++++++- 3 files changed, 63 insertions(+), 3 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/BeneficiaryPreferredCallDao.java b/src/main/java/net/gepafin/tendermanagement/dao/BeneficiaryPreferredCallDao.java index 60f8ea20..7daa089f 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/BeneficiaryPreferredCallDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/BeneficiaryPreferredCallDao.java @@ -2,13 +2,18 @@ package net.gepafin.tendermanagement.dao; import net.gepafin.tendermanagement.config.Translator; import net.gepafin.tendermanagement.constants.GepafinConstant; +import net.gepafin.tendermanagement.entities.ApplicationEntity; import net.gepafin.tendermanagement.entities.BeneficiaryPreferredCallEntity; import net.gepafin.tendermanagement.entities.UserEntity; import net.gepafin.tendermanagement.enums.BeneficiaryCallStatus; +import net.gepafin.tendermanagement.enums.VersionActionTypeEnum; import net.gepafin.tendermanagement.model.request.BeneficiaryPreferredCallReq; +import net.gepafin.tendermanagement.model.request.VersionHistoryRequest; import net.gepafin.tendermanagement.model.response.BeneficiaryPreferredCallResponseBean; import net.gepafin.tendermanagement.repositories.BeneficiaryPreferredCallRepository; +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; import net.gepafin.tendermanagement.web.rest.api.errors.ResourceNotFoundException; @@ -32,10 +37,15 @@ public class BeneficiaryPreferredCallDao { @Autowired private BeneficiaryPreferredCallRepository beneficiaryPreferredCallRepository; - + @Autowired private Validator validator; + @Autowired + private LoggingUtil loggingUtil; + + @Autowired + private HttpServletRequest httpServletRequest; public BeneficiaryPreferredCallResponseBean createBeneficiaryPreferredCall(HttpServletRequest httpServletRequest, BeneficiaryPreferredCallReq request, UserEntity user) { log.info("Creating new beneficiary preferred call with details: {}", request); @@ -51,6 +61,10 @@ public class BeneficiaryPreferredCallDao { BeneficiaryPreferredCallEntity entity = convertRequestToEntity(request, user); entity = beneficiaryPreferredCallRepository.save(entity); + + /** This code is responsible for adding a version history log for "Create Beneficiary Preferred Call" operation. **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(httpServletRequest).actionType(VersionActionTypeEnum.INSERT).oldData(null).newData(entity).build()); + log.info("Beneficiary preferred call created with ID: {}", entity.getId()); return convertEntityToResponse(entity); } @@ -92,13 +106,19 @@ public class BeneficiaryPreferredCallDao { log.info("Soft deleting beneficiary preferred call with ID: {}", id); BeneficiaryPreferredCallEntity entity = validateBeneficiaryPreferredCall(id); validator.validateUserId(request, entity.getUserId()); + BeneficiaryPreferredCallEntity oldBeneficiaryPreferredCallEntity = Utils.getClonedEntityForData(entity); entity.setIsDeleted(true); beneficiaryPreferredCallRepository.save(entity); + + /** This code is responsible for adding a version history log for the "Delete Beneficiary Preferred Call" operation. **/ + loggingUtil.addVersionHistory( + VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.SOFT_DELETE).oldData(oldBeneficiaryPreferredCallEntity).newData(entity).build()); + log.info("Beneficiary preferred call soft deleted with ID: {}", id); } public List getAllBeneficiaryPreferredCalls(HttpServletRequest request) { - UserEntity userEntity = validator.validateUser(request); + UserEntity userEntity = validator.validateUser(request); log.info("Fetching all beneficiary preferred calls"); List calls = beneficiaryPreferredCallRepository.findByUserIdAndIsDeletedFalse(userEntity.getId()) .stream() @@ -130,8 +150,13 @@ public class BeneficiaryPreferredCallDao { public void updateBeneficiaryPreferredCallStatus(Long id, BeneficiaryCallStatus status) { log.info("Updating status for beneficiary preferred call with ID: {}", id); BeneficiaryPreferredCallEntity existingEntity = validateBeneficiaryPreferredCall(id); + BeneficiaryPreferredCallEntity oldBeneficiaryPreferredCallEntity = Utils.getClonedEntityForData(existingEntity); existingEntity.setStatus(status.getValue()); beneficiaryPreferredCallRepository.save(existingEntity); + + /** This code is responsible for adding a version history log for the "Update Application" operation. **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(httpServletRequest).actionType(VersionActionTypeEnum.UPDATE).oldData(oldBeneficiaryPreferredCallEntity).newData(existingEntity).build()); + log.info("Beneficiary preferred call status updated with ID: {}", existingEntity.getId()); } public List getBeneficiaryPreferredCallByUserId(UserEntity userEntity, Long companyId) { diff --git a/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java index af692922..348fc019 100644 --- a/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java +++ b/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java @@ -50,6 +50,12 @@ public enum UserActionContextEnum { GET_APPLICATION_EVALUATION("GET_APPLICATION_EVALUATION"), DELETE_APPLICATION_EVALUATION("DELETE_APPLICATION_EVALUATION"), + /** Beneficiary Preferred Call action context **/ + CREATE_BENEFICIARY_PREFERRED_CALL("CREATE_BENEFICIARY_PREFERRED_CALL"), + DELETE_BENEFICIARY_PREFERRED_CALL("DELETE_BENEFICIARY_PREFERRED_CALL"), + GET_BENEFICIARY_PREFERRED_CALL("GET_BENEFICIARY_PREFERRED_CALL"), + UPDATE_BENEFICIARY_PREFERRED_CALL("UPDATE_BENEFICIARY_PREFERRED_CALL"), + /** Assigned Application action context **/ CREATE_ASSIGNED_APPLICATION("CREATE_ASSIGNED_APPLICATION"), DELETE_ASSIGNED_APPLICATION("DELETE_ASSIGNED_APPLICATION"), diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/BeneficiaryPreferredCallApiController.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/BeneficiaryPreferredCallApiController.java index d4e5b574..23a7e314 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/BeneficiaryPreferredCallApiController.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/BeneficiaryPreferredCallApiController.java @@ -4,11 +4,15 @@ import jakarta.servlet.http.HttpServletRequest; import net.gepafin.tendermanagement.config.Translator; import net.gepafin.tendermanagement.constants.GepafinConstant; import net.gepafin.tendermanagement.enums.BeneficiaryCallStatus; +import net.gepafin.tendermanagement.enums.UserActionContextEnum; +import net.gepafin.tendermanagement.enums.UserActionLogsEnum; import net.gepafin.tendermanagement.model.request.BeneficiaryPreferredCallReq; +import net.gepafin.tendermanagement.model.request.UserActionRequest; import net.gepafin.tendermanagement.model.response.BeneficiaryPreferredCallResponseBean; import net.gepafin.tendermanagement.model.util.Response; import net.gepafin.tendermanagement.service.BeneficiaryPreferredCallService; +import net.gepafin.tendermanagement.util.LoggingUtil; import net.gepafin.tendermanagement.web.rest.api.BeneficiaryPreferredCallApi; import net.gepafin.tendermanagement.web.rest.api.errors.Status; import org.slf4j.Logger; @@ -27,10 +31,16 @@ public class BeneficiaryPreferredCallApiController implements BeneficiaryPreferr @Autowired private BeneficiaryPreferredCallService beneficiaryPreferredCallService; - + @Autowired + private LoggingUtil loggingUtil; @Override public ResponseEntity> createBeneficiaryPreferredCall(HttpServletRequest request, BeneficiaryPreferredCallReq beneficiaryPreferredCallReq) { log.info("Creating Beneficiary Preferred Call"); + + /** This code is responsible for creating user action logs for the "Create Beneficiary Preferred Call" operation. **/ + loggingUtil.logUserAction( + UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.INSERT).actionContext(UserActionContextEnum.CREATE_BENEFICIARY_PREFERRED_CALL).build()); + BeneficiaryPreferredCallResponseBean responseBean = beneficiaryPreferredCallService.createBeneficiaryPreferredCall(request, beneficiaryPreferredCallReq); return ResponseEntity.status(HttpStatus.CREATED) .body(new Response<>(responseBean, Status.SUCCESS, Translator.toLocale(GepafinConstant.BENEFICIARY_PREFERRED_CALL_CREATED_SUCCESS_MSG))); @@ -47,6 +57,12 @@ public class BeneficiaryPreferredCallApiController implements BeneficiaryPreferr @Override public ResponseEntity> getBeneficiaryPreferredCallById(HttpServletRequest request, Long id) { log.info("Fetching Beneficiary Preferred Call by ID - ID: {}", id); + + + /** This code is responsible for creating user action logs for the "Get Beneficiary Preferred Call by id" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.VIEW) + .actionContext(UserActionContextEnum.GET_BENEFICIARY_PREFERRED_CALL).build()); + BeneficiaryPreferredCallResponseBean response = beneficiaryPreferredCallService.getBeneficiaryPreferredCallById(request, id); return ResponseEntity.status(HttpStatus.OK) .body(new Response<>(response, Status.SUCCESS, Translator.toLocale(GepafinConstant.GET_BENEFICIARY_PREFERRED_CALL_SUCCESS_MSG))); @@ -55,6 +71,10 @@ public class BeneficiaryPreferredCallApiController implements BeneficiaryPreferr @Override public ResponseEntity> deleteBeneficiaryPreferredCall(HttpServletRequest request, Long id) { log.info("Deleting Beneficiary Preferred Call - ID: {}", id); + + /** This code is responsible for creating user action logs for the "Delete Beneficiary Preferred Call" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.DELETE).actionContext(UserActionContextEnum.DELETE_BENEFICIARY_PREFERRED_CALL).build()); + beneficiaryPreferredCallService.deleteBeneficiaryPreferredCall(request, id); return ResponseEntity.status(HttpStatus.OK) .body(new Response<>(null, Status.SUCCESS, Translator.toLocale(GepafinConstant.DELETE_BENEFICIARY_PREFERRED_CALL_SUCCESS_MSG))); @@ -63,6 +83,11 @@ public class BeneficiaryPreferredCallApiController implements BeneficiaryPreferr @Override public ResponseEntity> updateBeneficiaryPreferredCallStatus(HttpServletRequest request, Long id, BeneficiaryCallStatus status) { log.info("Updating status of Beneficiary Preferred Call - ID: {}, Status: {}", id, status); + + /** This code is responsible for "Updating Beneficiary Preferred Call details" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.UPDATE) + .actionContext(UserActionContextEnum.UPDATE_BENEFICIARY_PREFERRED_CALL).build()); + beneficiaryPreferredCallService.updateBeneficiaryPreferredCallStatus(request, id, status); return ResponseEntity.status(HttpStatus.OK) .body(new Response<>(null, Status.SUCCESS, Translator.toLocale(GepafinConstant.BENEFICIARY_PREFERRED_CALL_STATUS_UPDATED_SUCCESS_MSG))); @@ -71,6 +96,10 @@ public class BeneficiaryPreferredCallApiController implements BeneficiaryPreferr @Override public ResponseEntity>> getBeneficiaryPreferredCallByUserId(HttpServletRequest request,Long userId,Long beneficiaryId,Long companyId) { log.info("Fetching all Beneficiary Preferred Calls for User ID"); + + /** This code is responsible for creating user action logs for the "Get Beneficiary Preferred Call" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.VIEW).actionContext(UserActionContextEnum.GET_BENEFICIARY_PREFERRED_CALL).build()); + List response = beneficiaryPreferredCallService.getBeneficiaryPreferredCallByUserId(request, userId,beneficiaryId,companyId); return ResponseEntity.status(HttpStatus.OK) .body(new Response<>(response, Status.SUCCESS, Translator.toLocale(GepafinConstant.GET_ALL_BENEFICIARY_PREFERRED_CALLS_SUCCESS_MSG))); From edafc797dc4db7ed2beca15696ddddab7363322c Mon Sep 17 00:00:00 2001 From: rajesh Date: Sun, 24 Nov 2024 16:46:56 +0530 Subject: [PATCH 17/43] Added audit for lookupData and Hub --- .../gepafin/tendermanagement/dao/HubDao.java | 29 ++++++++++-- .../tendermanagement/dao/LookUpDataDao.java | 19 ++++++-- .../enums/UserActionContextEnum.java | 15 ++++++ .../tendermanagement/service/HubService.java | 7 +-- .../service/impl/HubServiceImpl.java | 13 +++--- .../web/rest/api/impl/HubApiController.java | 46 ++++++++++++++++--- .../api/impl/LookUpDataApiController.java | 31 +++++++++++++ 7 files changed, 136 insertions(+), 24 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/HubDao.java b/src/main/java/net/gepafin/tendermanagement/dao/HubDao.java index ee6e0d8a..17143516 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/HubDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/HubDao.java @@ -1,12 +1,17 @@ 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.HubEntity; +import net.gepafin.tendermanagement.enums.VersionActionTypeEnum; import net.gepafin.tendermanagement.model.request.HubReq; +import net.gepafin.tendermanagement.model.request.VersionHistoryRequest; import net.gepafin.tendermanagement.model.response.HubResponseBean; import net.gepafin.tendermanagement.model.util.NanoIdUtils; import net.gepafin.tendermanagement.repositories.HubRepository; +import net.gepafin.tendermanagement.util.LoggingUtil; +import net.gepafin.tendermanagement.util.Utils; import net.gepafin.tendermanagement.web.rest.api.errors.ResourceNotFoundException; import net.gepafin.tendermanagement.web.rest.api.errors.Status; import org.springframework.beans.factory.annotation.Autowired; @@ -22,15 +27,26 @@ public class HubDao { @Autowired private HubRepository hubRepository; - public HubResponseBean createHub(HubReq hubReq) { + @Autowired + private LoggingUtil loggingUtil; + + public HubResponseBean createHub(HttpServletRequest request,HubReq hubReq) { HubEntity hubEntity = createOrUpdateHubEntity(new HubEntity(), hubReq); hubRepository.save(hubEntity); + + /** This code is responsible for adding a version history log for the "Create Hub" operation. **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.INSERT).oldData(null).newData(hubEntity).build()); + return convertToHubResponseBean(hubEntity); } - public HubResponseBean updateHub(Long hubId, HubReq hubReq) { + public HubResponseBean updateHub(HttpServletRequest request,Long hubId, HubReq hubReq) { HubEntity hubEntity = validateHub(hubId); - createOrUpdateHubEntity(hubEntity, hubReq); + HubEntity oldHubEntity = Utils.getClonedEntityForData(hubEntity); + HubEntity newHubEntity = createOrUpdateHubEntity(hubEntity, hubReq); + + /** This code is responsible for adding a version history log for the "Update Hub" operation. **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldHubEntity).newData(newHubEntity).build()); return convertToHubResponseBean(hubEntity); } @@ -43,10 +59,13 @@ public class HubDao { return hubs.stream().map(this::convertToHubResponseBean).toList(); } - public void deleteHub(Long hubId) { + public void deleteHub(HttpServletRequest request,Long hubId) { HubEntity hubEntity = validateHub(hubId); + + /** This code is responsible for adding a version history log for the "Delete Hub" operation. **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.DELETE).oldData(hubEntity).build()); + hubRepository.deleteById(hubId); - hubRepository.save(hubEntity); } public HubEntity validateHub(Long hubId) { diff --git a/src/main/java/net/gepafin/tendermanagement/dao/LookUpDataDao.java b/src/main/java/net/gepafin/tendermanagement/dao/LookUpDataDao.java index b1faf04c..ceb64f54 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/LookUpDataDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/LookUpDataDao.java @@ -3,7 +3,6 @@ package net.gepafin.tendermanagement.dao; import jakarta.servlet.http.HttpServletRequest; import net.gepafin.tendermanagement.entities.LookUpDataEntity; import net.gepafin.tendermanagement.entities.LookUpDataEntity.LookUpDataTypeEnum; -import net.gepafin.tendermanagement.enums.UserActionLogsEnum; import net.gepafin.tendermanagement.enums.VersionActionTypeEnum; import net.gepafin.tendermanagement.model.request.LookUpDataReq; import net.gepafin.tendermanagement.model.request.LookUpDataRequest; @@ -49,6 +48,9 @@ public class LookUpDataDao { entity.setValue(lookUpDataReq.getResponse()); validateLookUpDataEntity(entity); lookUpDataRepository.save(entity); + + /** This code is responsible for adding a version history log for the "Create LoopUpData" operation. **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.INSERT).oldData(null).newData(entity).build()); return entity; } @@ -69,16 +71,27 @@ public class LookUpDataDao { public LookUpDataResponseBean updateLookUpData(Long id, LookUpDataRequest lookUpDataReq) { LookUpDataEntity entity = validateLookUpData(id); + LookUpDataEntity oldLookUpData = Utils.getClonedEntityForData(entity); + setIfUpdated(entity::getTitle, entity::setTitle, lookUpDataReq.getTitle()); setIfUpdated(entity::getValue, entity::setValue, lookUpDataReq.getValue()); setIfUpdated(entity::getResponse, entity::setResponse, lookUpDataReq.getResponse()); lookUpDataRepository.save(entity); + + /** This code is responsible for adding a version history log for the "Update LookUpData" operation. **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldLookUpData).newData(entity).build()); + + return convertLookUpDataEntityToResponseBean(entity); } public void deleteLookUpData(Long id) { - LookUpDataEntity entity = validateLookUpData(id); - lookUpDataRepository.deleteById(entity.getId()); + LookUpDataEntity oldLookUpData = validateLookUpData(id); + + /** This code is responsible for adding a version history log for the "Delete LookUpData" operation. **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.DELETE).oldData(oldLookUpData).build()); + + lookUpDataRepository.deleteById(id); } private LookUpDataResponseBean convertLookUpDataEntityToResponseBean(LookUpDataEntity entity) { diff --git a/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java index b9be7dfa..9f828131 100644 --- a/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java +++ b/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java @@ -45,6 +45,21 @@ public enum UserActionContextEnum { UPDATE_FAQ_DETAILS("UPDATE_FAQ_DETAILS"), DELETE_FAQ("DELETE_FAQ"), + /** LookUpData action context **/ + CREATE_LOOKUP_DATA("CREATE_LOOKUP_DATA"), + DELETE_LOOKUP_DATA("DELETE_LOOKUP_DATA"), + UPDATE_LOOKUP_DATA("UPDATE_LOOKUP_DATA"), + GET_LOOKUP_DATA("GET_LOOKUP_DATA"), + GET_LOOKUP_DATA_BY_TYPE("GET_LOOKUP_DATA_BY_TYPE"), + + /** Hub action context **/ + CREATE_HUB("CREATE_HUB"), + GET_HUB("GET_HUB"), + DELETE_HUB("DELETE_HUB"), + UPDATE_HUB("UPDATE_HUB"), + GET_ALL_HUB("GET_ALL_HUB"), + GET_HUB_BY_UUID(" GET_HUB_BY_UUID"), + /** Assigned Application action context **/ CREATE_ASSIGNED_APPLICATION("CREATE_ASSIGNED_APPLICATION"), DELETE_ASSIGNED_APPLICATION("DELETE_ASSIGNED_APPLICATION"), diff --git a/src/main/java/net/gepafin/tendermanagement/service/HubService.java b/src/main/java/net/gepafin/tendermanagement/service/HubService.java index ad763419..dc2a4272 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/HubService.java +++ b/src/main/java/net/gepafin/tendermanagement/service/HubService.java @@ -1,6 +1,7 @@ package net.gepafin.tendermanagement.service; +import jakarta.servlet.http.HttpServletRequest; import net.gepafin.tendermanagement.entities.HubEntity; import net.gepafin.tendermanagement.model.request.HubReq; import net.gepafin.tendermanagement.model.response.HubResponseBean; @@ -8,11 +9,11 @@ import net.gepafin.tendermanagement.model.response.HubResponseBean; import java.util.List; public interface HubService { - HubResponseBean createHub(HubReq hubReq); - HubResponseBean updateHub(Long hubId, HubReq hubReq); + HubResponseBean createHub(HttpServletRequest request,HubReq hubReq); + HubResponseBean updateHub(HttpServletRequest request,Long hubId, HubReq hubReq); HubResponseBean getHubById(Long hubId); List getAllHubs(); - void deleteHub(Long hubId); + void deleteHub(HttpServletRequest request,Long hubId); HubEntity getHubByUuid(String hubUuid); HubResponseBean getHubByHubUuid(String uuid); HubEntity valdateHub(Long hubId); diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/HubServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/HubServiceImpl.java index 3490a0e6..c48d7a59 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/HubServiceImpl.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/HubServiceImpl.java @@ -1,5 +1,6 @@ package net.gepafin.tendermanagement.service.impl; +import jakarta.servlet.http.HttpServletRequest; import net.gepafin.tendermanagement.dao.HubDao; import net.gepafin.tendermanagement.entities.HubEntity; import net.gepafin.tendermanagement.model.request.HubReq; @@ -19,14 +20,14 @@ public class HubServiceImpl implements HubService { @Override @Transactional(rollbackFor = Exception.class) - public HubResponseBean createHub(HubReq hubReq) { - return hubDao.createHub(hubReq); + public HubResponseBean createHub(HttpServletRequest request,HubReq hubReq) { + return hubDao.createHub(request,hubReq); } @Override @Transactional(rollbackFor = Exception.class) - public HubResponseBean updateHub(Long hubId, HubReq hubReq) { - return hubDao.updateHub(hubId, hubReq); + public HubResponseBean updateHub(HttpServletRequest request,Long hubId, HubReq hubReq) { + return hubDao.updateHub(request,hubId, hubReq); } @Override @@ -43,8 +44,8 @@ public class HubServiceImpl implements HubService { @Override @Transactional(rollbackFor = Exception.class) - public void deleteHub(Long hubId) { - hubDao.deleteHub(hubId); + public void deleteHub(HttpServletRequest request,Long hubId) { + hubDao.deleteHub(request,hubId); } @Override diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/HubApiController.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/HubApiController.java index 7e8828e0..9fcd8455 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/HubApiController.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/HubApiController.java @@ -4,10 +4,14 @@ import jakarta.servlet.http.HttpServletRequest; import jakarta.validation.Valid; 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.HubReq; +import net.gepafin.tendermanagement.model.request.UserActionRequest; import net.gepafin.tendermanagement.model.response.HubResponseBean; import net.gepafin.tendermanagement.model.util.Response; import net.gepafin.tendermanagement.service.HubService; +import net.gepafin.tendermanagement.util.LoggingUtil; import net.gepafin.tendermanagement.web.rest.api.HubApi; import net.gepafin.tendermanagement.web.rest.api.errors.Status; @@ -24,17 +28,29 @@ public class HubApiController implements HubApi { @Autowired private HubService hubService; + @Autowired + private LoggingUtil loggingUtil; + @Override public ResponseEntity> createHub(HttpServletRequest request, @Valid HubReq hubReq) { - HubResponseBean hubResponse = hubService.createHub(hubReq); + + /** This code is responsible for creating user action logs for the "Create Hub" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.INSERT) + .actionContext(UserActionContextEnum.CREATE_HUB).build()); + + HubResponseBean hubResponse = hubService.createHub(request,hubReq); return ResponseEntity.status(HttpStatus.CREATED) .body(new Response<>(hubResponse, Status.SUCCESS, Translator.toLocale(GepafinConstant.HUB_CREATE_SUCCESS))); } @Override public ResponseEntity> updateHub(HttpServletRequest request, Long hubId, @Valid HubReq hubReq) { - - HubResponseBean hubResponse = hubService.updateHub(hubId, hubReq); + + /** This code is responsible for "Updating Hub details" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.UPDATE) + .actionContext(UserActionContextEnum.UPDATE_HUB).build()); + + HubResponseBean hubResponse = hubService.updateHub(request,hubId, hubReq); return ResponseEntity.status(HttpStatus.OK) .body(new Response<>(hubResponse, Status.SUCCESS, Translator.toLocale(GepafinConstant.HUB_UPDATE_SUCCESS))); @@ -42,7 +58,11 @@ public class HubApiController implements HubApi { @Override public ResponseEntity> getHubById(HttpServletRequest request, Long hubId) { - + + /** This code is responsible for creating user action logs for the "get hub by id" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.VIEW) + .actionContext(UserActionContextEnum.GET_HUB).build()); + HubResponseBean hubResponse = hubService.getHubById(hubId); return ResponseEntity.status(HttpStatus.OK) @@ -51,7 +71,11 @@ public class HubApiController implements HubApi { @Override public ResponseEntity>> getAllHubs(HttpServletRequest request) { - + + /** This code is responsible for creating user action logs for the "get all hub" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.VIEW) + .actionContext(UserActionContextEnum.GET_ALL_HUB).build()); + List hubs = hubService.getAllHubs(); return ResponseEntity.status(HttpStatus.OK) .body(new Response<>(hubs, Status.SUCCESS, Translator.toLocale(GepafinConstant.HUB_GET_ALL_SUCCESS))); @@ -59,13 +83,21 @@ public class HubApiController implements HubApi { @Override public ResponseEntity> deleteHub(HttpServletRequest request, Long hubId) { - - hubService.deleteHub(hubId); + + /** This code is responsible for creating user action logs for the "Delete Hub" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.DELETE).actionContext(UserActionContextEnum.DELETE_HUB).build()); + + hubService.deleteHub(request,hubId); return ResponseEntity.status(HttpStatus.OK) .body(new Response<>(null, Status.SUCCESS, Translator.toLocale(GepafinConstant.HUB_DELETE_SUCCESS))); } @Override public ResponseEntity> getHubByUuid(HttpServletRequest request, String uuid) { + + /** This code is responsible for creating user action logs for the "get hub by uuid" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.VIEW) + .actionContext(UserActionContextEnum.GET_HUB_BY_UUID).build()); + HubResponseBean hubResponse = hubService.getHubByHubUuid(uuid); return ResponseEntity.status(HttpStatus.OK) .body(new Response<>(hubResponse, Status.SUCCESS, Translator.toLocale(GepafinConstant.HUB_GET_SUCCESS))); diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/LookUpDataApiController.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/LookUpDataApiController.java index 3f79198c..d8e18e32 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/LookUpDataApiController.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/LookUpDataApiController.java @@ -4,10 +4,14 @@ import jakarta.servlet.http.HttpServletRequest; import net.gepafin.tendermanagement.config.Translator; import net.gepafin.tendermanagement.constants.GepafinConstant; import net.gepafin.tendermanagement.entities.LookUpDataEntity.LookUpDataTypeEnum; +import net.gepafin.tendermanagement.enums.UserActionContextEnum; +import net.gepafin.tendermanagement.enums.UserActionLogsEnum; import net.gepafin.tendermanagement.model.request.LookUpDataRequest; +import net.gepafin.tendermanagement.model.request.UserActionRequest; import net.gepafin.tendermanagement.model.response.LookUpDataResponseBean; import net.gepafin.tendermanagement.model.util.Response; import net.gepafin.tendermanagement.service.LookUpDataService; +import net.gepafin.tendermanagement.util.LoggingUtil; import net.gepafin.tendermanagement.web.rest.api.LookUpDataApi; import net.gepafin.tendermanagement.web.rest.api.errors.Status; import org.springframework.beans.factory.annotation.Autowired; @@ -25,8 +29,16 @@ public class LookUpDataApiController implements LookUpDataApi { @Autowired private LookUpDataService lookUpDataService; + @Autowired + LoggingUtil loggingUtil; + @Override public ResponseEntity> createLookUpData(HttpServletRequest request, LookUpDataRequest lookUpDataReq) { + + /** This code is responsible for creating user action logs for the "Create LoopUpData" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.INSERT) + .actionContext(UserActionContextEnum.CREATE_LOOKUP_DATA).build()); + LookUpDataResponseBean responseBean = lookUpDataService.createLookUpData(lookUpDataReq); return ResponseEntity.status(HttpStatus.CREATED) .body(new Response(responseBean, Status.SUCCESS, Translator.toLocale(GepafinConstant.LOOKUP_DATA_CREATED_SUCCESSFULLY))); @@ -34,6 +46,11 @@ public class LookUpDataApiController implements LookUpDataApi { @Override public ResponseEntity> getLookUpDataById(HttpServletRequest request, Long id) { + + /** This code is responsible for creating user action logs for the "get lookup data by id" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.VIEW) + .actionContext(UserActionContextEnum.GET_LOOKUP_DATA).build()); + LookUpDataResponseBean responseBean = lookUpDataService.getLookUpDataById(id); if (responseBean != null) { return ResponseEntity.status(HttpStatus.OK) @@ -46,6 +63,11 @@ public class LookUpDataApiController implements LookUpDataApi { @Override public ResponseEntity> updateLookUpData(HttpServletRequest request, Long id, LookUpDataRequest lookUpDataReq) { + + /** This code is responsible for "Updating LookUp Data details" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.UPDATE) + .actionContext(UserActionContextEnum.UPDATE_LOOKUP_DATA).build()); + LookUpDataResponseBean responseBean = lookUpDataService.updateLookUpData(id, lookUpDataReq); if (responseBean != null) { return ResponseEntity.status(HttpStatus.OK) @@ -58,12 +80,21 @@ public class LookUpDataApiController implements LookUpDataApi { @Override public ResponseEntity> deleteLookUpData(HttpServletRequest request, Long id) { + + /** This code is responsible for creating user action logs for the "Delete LookUpData" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.DELETE).actionContext(UserActionContextEnum.DELETE_LOOKUP_DATA).build()); + lookUpDataService.deleteLookUpData(id); return ResponseEntity.status(HttpStatus.OK) .body(new Response<>(null, Status.SUCCESS, Translator.toLocale(GepafinConstant.LOOKUP_DATA_DELETED_SUCCESSFULLY))); } @Override public ResponseEntity>> getLookUpDataByType(HttpServletRequest request, List type) { + + /** This code is responsible for creating user action logs for the "get lookup data by type" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.VIEW) + .actionContext(UserActionContextEnum.GET_LOOKUP_DATA_BY_TYPE).build()); + List responseBean = lookUpDataService.getLookUpDataByType(type); if (responseBean != null) { return ResponseEntity.status(HttpStatus.OK) From 0b9eebb9e9ca137956573f7c532ce49389cb853c Mon Sep 17 00:00:00 2001 From: piyushkag Date: Sun, 24 Nov 2024 18:34:34 +0530 Subject: [PATCH 18/43] Added user action and versioning for company. --- .../tendermanagement/dao/CompanyDao.java | 119 +++++++++++++----- .../tendermanagement/dao/DelegationDao.java | 46 +++++-- .../tendermanagement/dao/VatCheckDao.java | 19 ++- .../enums/UserActionContextEnum.java | 18 ++- .../service/impl/CompanyServiceImpl.java | 5 +- .../rest/api/impl/CompanyApiController.java | 92 ++++++++++---- 6 files changed, 232 insertions(+), 67 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/CompanyDao.java b/src/main/java/net/gepafin/tendermanagement/dao/CompanyDao.java index 84b01021..38e856c0 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/CompanyDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/CompanyDao.java @@ -2,10 +2,14 @@ package net.gepafin.tendermanagement.dao; import java.util.List; +import jakarta.servlet.http.HttpServletRequest; import net.gepafin.tendermanagement.entities.*; import net.gepafin.tendermanagement.enums.ApplicationStatusTypeEnum; +import net.gepafin.tendermanagement.enums.VersionActionTypeEnum; +import net.gepafin.tendermanagement.model.request.VersionHistoryRequest; import net.gepafin.tendermanagement.repositories.ApplicationRepository; import net.gepafin.tendermanagement.repositories.FaqRepository; +import net.gepafin.tendermanagement.util.LoggingUtil; import net.gepafin.tendermanagement.web.rest.api.errors.*; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; @@ -38,25 +42,38 @@ public class CompanyDao { @Autowired private FaqRepository faqRepository; + @Autowired + private LoggingUtil loggingUtil; + + @Autowired + private HttpServletRequest request; public CompanyResponse createCompany(UserEntity userEntity, CompanyRequest companyRequest) { + CompanyEntity existingCompany = companyRepository.findByVatNumberAndHubId(companyRequest.getVatNumber(), userEntity.getHub().getId()); UserWithCompanyEntity userWithCompanyEntity = null; if (existingCompany != null) { - UserWithCompanyEntity existingRelation = userWithCompanyRepository.findByUserIdAndCompanyIdAndIsDeletedFalse(userEntity.getId(), existingCompany.getId()) - .orElse(null); + UserWithCompanyEntity existingRelation = userWithCompanyRepository.findByUserIdAndCompanyIdAndIsDeletedFalse(userEntity.getId(), existingCompany.getId()).orElse(null); if (existingRelation == null) { userWithCompanyEntity = createUserWithCompanyRelation(userEntity, existingCompany, companyRequest.getIsLegalRepresentant()); + + /** This code is responsible for adding a version history log for "adding user with company" operation. **/ + loggingUtil.addVersionHistory( + VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.INSERT).oldData(null).newData(userWithCompanyEntity).build()); } else { - throw new CustomValidationException(Status.VALIDATION_ERROR, - Translator.toLocale(GepafinConstant.USER_ALREADY_CONNECTED_TO_COMPANY)); + throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.USER_ALREADY_CONNECTED_TO_COMPANY)); } return convertCompanyEntityToCompanyResponse(existingCompany, userWithCompanyEntity); } else { validateCompany(userEntity, companyRequest); CompanyEntity companyEntity = convertCompanyRequestToCompanyEntity(userEntity, companyRequest); - companyRepository.save(companyEntity); + CompanyEntity companyData = companyRepository.save(companyEntity); + + /** This code is responsible for adding a version history log for "creating company" operation. **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.INSERT).oldData(null).newData(companyData).build()); + userWithCompanyEntity = createUserWithCompanyRelation(userEntity, companyEntity, companyRequest.getIsLegalRepresentant()); + return convertCompanyEntityToCompanyResponse(companyEntity, userWithCompanyEntity); } } @@ -80,6 +97,7 @@ public class CompanyDao { } private UserWithCompanyEntity createUserWithCompanyRelation(UserEntity userEntity, CompanyEntity companyEntity, Boolean isLegalRepresentant) { + UserWithCompanyEntity userWithCompanyEntity = new UserWithCompanyEntity(); if (userEntity.getBeneficiary() != null) { userWithCompanyEntity.setBeneficiaryId(userEntity.getBeneficiary().getId()); @@ -88,7 +106,11 @@ public class CompanyDao { userWithCompanyEntity.setCompanyId(companyEntity.getId()); userWithCompanyEntity.setUserId(userEntity.getId()); userWithCompanyEntity.setIsLegalRepresentant(isLegalRepresentant); - return userWithCompanyRepository.save(userWithCompanyEntity); + UserWithCompanyEntity userWithCompany = userWithCompanyRepository.save(userWithCompanyEntity); + + /** This code is responsible for adding a version history log for the "adding user with company" operation. **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.INSERT).oldData(null).newData(userWithCompany).build()); + return userWithCompany; } private CompanyEntity convertCompanyRequestToCompanyEntity(UserEntity userEntity, CompanyRequest request) { @@ -139,32 +161,43 @@ public class CompanyDao { } public CompanyResponse updateCompany(UserEntity userEntity, Long companyId, CompanyRequest companyRequest) { + CompanyEntity companyEntity = validateCompany(companyId); - setIfUpdated(companyEntity::getCompanyName, companyEntity::setCompanyName, - companyRequest.getCompanyName()); + //cloned entity for old data + CompanyEntity oldCompanyData = Utils.getClonedEntityForData(companyEntity); + + setIfUpdated(companyEntity::getCompanyName, companyEntity::setCompanyName, companyRequest.getCompanyName()); setIfUpdated(companyEntity::getVatNumber, companyEntity::setVatNumber, companyRequest.getVatNumber()); - setIfUpdated(companyEntity::getCodiceFiscale, companyEntity::setCodiceFiscale, - companyRequest.getCodiceFiscale()); + setIfUpdated(companyEntity::getCodiceFiscale, companyEntity::setCodiceFiscale, companyRequest.getCodiceFiscale()); setIfUpdated(companyEntity::getAddress, companyEntity::setAddress, companyRequest.getAddress()); - setIfUpdated(companyEntity::getPhoneNumber, companyEntity::setPhoneNumber, - companyRequest.getPhoneNumber()); + setIfUpdated(companyEntity::getPhoneNumber, companyEntity::setPhoneNumber, companyRequest.getPhoneNumber()); setIfUpdated(companyEntity::getCity, companyEntity::setCity, companyRequest.getCity()); setIfUpdated(companyEntity::getProvince, companyEntity::setProvince, companyRequest.getProvince()); setIfUpdated(companyEntity::getCap, companyEntity::setCap, companyRequest.getCap()); setIfUpdated(companyEntity::getCountry, companyEntity::setCountry, companyRequest.getCountry()); setIfUpdated(companyEntity::getPec, companyEntity::setPec, companyRequest.getPec()); setIfUpdated(companyEntity::getEmail, companyEntity::setEmail, companyRequest.getEmail()); - setIfUpdated(companyEntity::getNumberOfEmployees, companyEntity::setNumberOfEmployees, - companyRequest.getNumberOfEmployees()); - setIfUpdated(companyEntity::getAnnualRevenue, companyEntity::setAnnualRevenue, - companyRequest.getAnnualRevenue()); - setIfUpdated(companyEntity::getContactName,companyEntity::setContactName,companyRequest.getContactName()); - setIfUpdated(companyEntity::getContactEmail,companyEntity::setContactEmail,companyRequest.getContactEmail()); + setIfUpdated(companyEntity::getNumberOfEmployees, companyEntity::setNumberOfEmployees, companyRequest.getNumberOfEmployees()); + setIfUpdated(companyEntity::getAnnualRevenue, companyEntity::setAnnualRevenue, companyRequest.getAnnualRevenue()); + setIfUpdated(companyEntity::getContactName, companyEntity::setContactName, companyRequest.getContactName()); + setIfUpdated(companyEntity::getContactEmail, companyEntity::setContactEmail, companyRequest.getContactEmail()); companyRepository.save(companyEntity); + + /** This code is responsible for adding a version history log for the "Update company" operation. **/ + loggingUtil.addVersionHistory( + VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldCompanyData).newData(companyEntity).build()); + UserWithCompanyEntity userWithCompanyEntity = getUserWithCompany(userEntity.getId(), companyId); - Utils.setIfUpdated(userWithCompanyEntity::getIsLegalRepresentant, userWithCompanyEntity::setIsLegalRepresentant, - companyRequest.getIsLegalRepresentant()); - userWithCompanyRepository.save(userWithCompanyEntity); + //cloned entity for old data + UserWithCompanyEntity oldUserWithCompanyData = Utils.getClonedEntityForData(userWithCompanyEntity); + + Utils.setIfUpdated(userWithCompanyEntity::getIsLegalRepresentant, userWithCompanyEntity::setIsLegalRepresentant, companyRequest.getIsLegalRepresentant()); + userWithCompanyEntity = userWithCompanyRepository.save(userWithCompanyEntity); + + /** This code is responsible for adding a version history log for the "Update company" operation. **/ + loggingUtil.addVersionHistory( + VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldUserWithCompanyData).newData(userWithCompanyEntity).build()); + return convertCompanyEntityToCompanyResponse(companyEntity, userWithCompanyEntity); } @@ -179,8 +212,20 @@ public class CompanyDao { } public void deleteCompany(UserEntity userEntity, Long companyId) { + CompanyEntity companyEntity = validateCompany(companyId); + + /** This code is responsible for adding a version history log for the "delete company" operation. **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.DELETE).oldData(companyEntity).newData(null).build()); + companyRepository.delete(companyEntity); + + UserWithCompanyEntity userWithCompanyEntity = getUserWithCompany(userEntity.getId(), companyId); + + /** This code is responsible for adding a version history log for the "delete user with company" operation. **/ + loggingUtil.addVersionHistory( + VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.DELETE).oldData(userWithCompanyEntity).newData(null).build()); + userWithCompanyRepository.deleteByCompanyIdAndIsDeletedFalse(companyId); } @@ -204,26 +249,44 @@ public class CompanyDao { () -> new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.USER_COMPANY_RELATION_NOT_FOUND))); } public void removeCompanyFromList(UserEntity userEntity, Long companyId) { + CompanyEntity companyEntity = validateCompany(companyId); UserWithCompanyEntity existingRelation = userWithCompanyRepository.findByUserIdAndCompanyIdAndIsDeletedFalse(userEntity.getId(), companyEntity.getId()) - .orElseThrow(() -> new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.USER_ALREADY_CONNECTED_TO_COMPANY))); + .orElseThrow(() -> new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.USER_ALREADY_CONNECTED_TO_COMPANY))); List userApplications = applicationRepository.findByCompanyIdAndUserIdAndIsDeletedFalse(companyEntity.getId(), userEntity.getId()); List faqs = faqRepository.findByCompanyIdAndUserIdAndIsDeletedFalse(companyEntity.getId(), userEntity.getId()); for (ApplicationEntity application : userApplications) { - if(Boolean.TRUE.equals(application.getStatus().equals(ApplicationStatusTypeEnum.SUBMIT.getValue()))) { - throw new CustomValidationException(Status.BAD_REQUEST,Translator.toLocale(GepafinConstant.CANNOT_DELETE_COMPANY_WITH_APPLICATION_SUBMITT)); + if (Boolean.TRUE.equals(application.getStatus().equals(ApplicationStatusTypeEnum.SUBMIT.getValue()))) { + throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.CANNOT_DELETE_COMPANY_WITH_APPLICATION_SUBMITT)); } - if(Boolean.TRUE.equals(application.getStatus().equals(ApplicationStatusTypeEnum.DRAFT.getValue()))) { + if (Boolean.TRUE.equals(application.getStatus().equals(ApplicationStatusTypeEnum.DRAFT.getValue()))) { + + //cloned entity for old data + ApplicationEntity oldApplicationData = Utils.getClonedEntityForData(application); application.setIsDeleted(Boolean.TRUE); applicationRepository.save(application); + + /** This code is responsible for adding a version history log for the "" operation. **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.SOFT_DELETE).oldData(oldApplicationData).newData(application).build()); } } - for(FaqEntity faq:faqs) { - faq.setIsDeleted(Boolean.TRUE); - faqRepository.save(faq); + for (FaqEntity faq : faqs) { + //cloned for old data + FaqEntity oldFaqEntityData = Utils.getClonedEntityForData(faq); + faq.setIsDeleted(Boolean.TRUE); + faqRepository.save(faq); + + /** This code is responsible for adding a version history log for the "soft deleting faq" operation. **/ + loggingUtil.addVersionHistory( + VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.SOFT_DELETE).oldData(oldFaqEntityData).newData(faq).build()); } + UserWithCompanyEntity oldUserWithCompanyData = Utils.getClonedEntityForData(existingRelation); existingRelation.setIsDeleted(Boolean.TRUE); userWithCompanyRepository.save(existingRelation); + + /** This code is responsible for adding a version history log for the "soft deleting existing user relation" operation. **/ + loggingUtil.addVersionHistory( + VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.SOFT_DELETE).oldData(oldUserWithCompanyData).newData(existingRelation).build()); } } diff --git a/src/main/java/net/gepafin/tendermanagement/dao/DelegationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/DelegationDao.java index dfc65ec7..5c2c7e70 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/DelegationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/DelegationDao.java @@ -9,6 +9,9 @@ import java.util.function.Function; import net.gepafin.tendermanagement.enums.DocOtherSourceTypeEnum; +import net.gepafin.tendermanagement.enums.VersionActionTypeEnum; +import net.gepafin.tendermanagement.model.request.VersionHistoryRequest; +import net.gepafin.tendermanagement.util.LoggingUtil; import org.apache.commons.lang3.StringUtils; import org.apache.poi.xwpf.usermodel.XWPFDocument; import org.springframework.beans.factory.annotation.Autowired; @@ -67,6 +70,12 @@ public class DelegationDao { @Autowired private Validator validator; + @Autowired + private LoggingUtil loggingUtil; + + @Autowired + private HttpServletRequest request; + public ByteArrayOutputStream generateDocument(Map placeholders, String templateName) { try { String s3Folder = s3ConfigBean.generateDocumentPathForOther(DocOtherSourceTypeEnum.TEMPLATE, 0L, 0L); @@ -176,18 +185,22 @@ public class DelegationDao { placeholders.put(key, formatter.apply(value)); } } - public CompanyDelegationResponse uploadCompanyDelegation(UserEntity userEntity, Long companyId, MultipartFile file) { + companyDao.validateCompany(companyId); companyDao.getUserWithCompany(userEntity.getId(), companyId); validateFileType(file); - UserCompanyDelegationEntity userCompanyDelegationEntity = userCompanyDelegationRepository - .findByUserIdAndCompanyIdAndStatus(userEntity.getId(), companyId, - UserCompanyDelegationStatusEnum.ACTIVE.getValue()); + UserCompanyDelegationEntity userCompanyDelegationEntity = userCompanyDelegationRepository.findByUserIdAndCompanyIdAndStatus(userEntity.getId(), companyId, + UserCompanyDelegationStatusEnum.ACTIVE.getValue()); + UserCompanyDelegationEntity oldUserCompanyDelegationEntity = Utils.getClonedEntityForData(userCompanyDelegationEntity); if (userCompanyDelegationEntity != null) { userCompanyDelegationEntity.setStatus(UserCompanyDelegationStatusEnum.INACTIVE.getValue()); userCompanyDelegationRepository.save(userCompanyDelegationEntity); + + /** This code is responsible for adding a version history log for the "update user company delegation status" operation. **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldUserCompanyDelegationEntity) + .newData(userCompanyDelegationEntity).build()); } UploadFileOnAmazonS3Response uploadFileOnAmazonS3Response = uploadFileOnAmazonS3ForCompanyDelegation(file); userCompanyDelegationEntity = new UserCompanyDelegationEntity(); @@ -200,8 +213,14 @@ public class DelegationDao { userCompanyDelegationEntity.setFileName(uploadFileOnAmazonS3Response.getFileName()); userCompanyDelegationEntity.setFilePath(uploadFileOnAmazonS3Response.getFilePath()); userCompanyDelegationRepository.save(userCompanyDelegationEntity); + + /** This code is responsible for adding a version history log for the "Insert or upload user company delegation" operation. **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.INSERT).oldData(null) + .newData(userCompanyDelegationEntity).build()); + return convertUserCompanyDelegationToCompanyDelegationResponse(userCompanyDelegationEntity); } + private UploadFileOnAmazonS3Response uploadFileOnAmazonS3ForCompanyDelegation(MultipartFile file) { try { String s3Path = generateS3PathForDelegation(); @@ -247,15 +266,22 @@ public class DelegationDao { } public void deleteCompanyDelegation(UserEntity userEntity, Long companyId) { - UserCompanyDelegationEntity userCompanyDelegationEntity = userCompanyDelegationRepository - .findByUserIdAndCompanyIdAndStatus(userEntity.getId(), companyId, - UserCompanyDelegationStatusEnum.ACTIVE.getValue()); + + UserCompanyDelegationEntity userCompanyDelegationEntity = userCompanyDelegationRepository.findByUserIdAndCompanyIdAndStatus(userEntity.getId(), companyId, + UserCompanyDelegationStatusEnum.ACTIVE.getValue()); companyDao.getUserWithCompany(userEntity.getId(), companyId); - if(userCompanyDelegationEntity == null) { - throw new ResourceNotFoundException(Status.NOT_FOUND, - Translator.toLocale(GepafinConstant.DELEGATION_NOT_FOUND)); + //cloned entity for old data + UserCompanyDelegationEntity oldUserCompanyDelegation = Utils.getClonedEntityForData(userCompanyDelegationEntity); + + if (userCompanyDelegationEntity == null) { + throw new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.DELEGATION_NOT_FOUND)); } userCompanyDelegationEntity.setStatus(UserCompanyDelegationStatusEnum.INACTIVE.getValue()); userCompanyDelegationRepository.save(userCompanyDelegationEntity); + + /** This code is responsible for adding a version history log for the "Soft Deleting company delegation " operation. **/ + loggingUtil.addVersionHistory( + VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.SOFT_DELETE).oldData(oldUserCompanyDelegation).newData(userCompanyDelegationEntity) + .build()); } } diff --git a/src/main/java/net/gepafin/tendermanagement/dao/VatCheckDao.java b/src/main/java/net/gepafin/tendermanagement/dao/VatCheckDao.java index f4a07849..1a4c110d 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/VatCheckDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/VatCheckDao.java @@ -1,9 +1,14 @@ package net.gepafin.tendermanagement.dao; import feign.FeignException; +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.UserActionRequest; import net.gepafin.tendermanagement.service.feignClient.VatCheckService; +import net.gepafin.tendermanagement.util.LoggingUtil; import net.gepafin.tendermanagement.util.Utils; import net.gepafin.tendermanagement.web.rest.api.errors.CustomValidationException; import net.gepafin.tendermanagement.web.rest.api.errors.Status; @@ -38,9 +43,14 @@ public class VatCheckDao { public final Logger log = LoggerFactory.getLogger(VatCheckDao.class); + @Autowired + private LoggingUtil loggingUtil; + @Autowired + private HttpServletRequest request; public Map checkVatNumberApi(String vatNumber) { + if (Boolean.TRUE.equals(Boolean.parseBoolean(isVatCheckGloballyDisabled))) { return new HashMap<>(); } @@ -50,11 +60,14 @@ public class VatCheckDao { headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON)); headers.setContentType(MediaType.APPLICATION_JSON); headers.set(GepafinConstant.AUTHORIZATION, "Bearer " + vatCheckNewToken); - headers.add(org.apache.http.HttpHeaders.USER_AGENT, - "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0"); + headers.add(org.apache.http.HttpHeaders.USER_AGENT, "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0"); URI baseUrl = URI.create(GepafinConstant.CHECK_VATNUMBER_V2_NEW_URL); - ResponseEntity> response = vatCheckService.checkVatNumber(baseUrl,vatNumber, headers); + ResponseEntity> response = vatCheckService.checkVatNumber(baseUrl, vatNumber, headers); + + /** This code is responsible for creating user action logs for the "Download company delegation" operation. **/ + loggingUtil.logUserAction( + UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.VIEW).actionContext(UserActionContextEnum.CHECK_COMPANY_VAT_NUMBER).build()); if (response.getStatusCode() == HttpStatus.OK && response.hasBody()) { log.info("Successfully checked vat number"); diff --git a/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java index c269e62f..7a694931 100644 --- a/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java +++ b/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java @@ -45,6 +45,19 @@ public enum UserActionContextEnum { UPDATE_FAQ_DETAILS("UPDATE_FAQ_DETAILS"), DELETE_FAQ("DELETE_FAQ"), + /** company action context **/ + CREATE_COMPANY("CREATE_COMPANY"), + GET_COMPANY("GET_COMPANY"), + UPDATE_COMPANY("UPDATE_COMPANY"), + DELETE_COMPANY("DELETE_COMPANY"), + UPLOAD_COMPANY_DELEGATION("UPLOAD_COMPANY_DELEGATION"), + DOWNLOAD_COMPANY_DELEGATION_TEMPLATE("DOWNLOAD_COMPANY_DELEGATION_TEMPLATE"), + GET_COMPANY_DELEGATION("GET_COMPANY_DELEGATION"), + DELETE_COMPANY_DELEGATION("DELETE_COMPANY_DELEGATION"), + CHECK_COMPANY_VAT_NUMBER("CHECK_COMPANY_VAT_NUMBER"), + GET_COMPANY_BY_USER("GET_COMPANY_BY_USER"), + REMOVE_COMPANY_FROM_USER("REMOVE_COMPANY_FROM_USER"), + /** LookUpData action context **/ CREATE_LOOKUP_DATA("CREATE_LOOKUP_DATA"), DELETE_LOOKUP_DATA("DELETE_LOOKUP_DATA"), @@ -70,13 +83,12 @@ public enum UserActionContextEnum { DELETE_BENEFICIARY_PREFERRED_CALL("DELETE_BENEFICIARY_PREFERRED_CALL"), GET_BENEFICIARY_PREFERRED_CALL("GET_BENEFICIARY_PREFERRED_CALL"), UPDATE_BENEFICIARY_PREFERRED_CALL("UPDATE_BENEFICIARY_PREFERRED_CALL"), - + /** Assigned Application action context **/ CREATE_ASSIGNED_APPLICATION("CREATE_ASSIGNED_APPLICATION"), DELETE_ASSIGNED_APPLICATION("DELETE_ASSIGNED_APPLICATION"), GET_ASSIGNED_APPLICATION("GET_ASSIGNED_APPLICATION"), - UPDATE_ASSIGNED_APPLICATION_DETAILS("UPDATE_ASSIGNED_APPLICATION_DETAILS") - ; + UPDATE_ASSIGNED_APPLICATION_DETAILS("UPDATE_ASSIGNED_APPLICATION_DETAILS"); private final String value; diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/CompanyServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/CompanyServiceImpl.java index 5ab99b13..c6bcc2f1 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/CompanyServiceImpl.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/CompanyServiceImpl.java @@ -106,7 +106,7 @@ public class CompanyServiceImpl implements CompanyService { } @Override - @Transactional(readOnly = true) + @Transactional public CompanyDelegationResponse getCompanyDelegation(HttpServletRequest request, Long companyId) { UserEntity userEntity =validator.validateUser(request); return delegationDao.getCompanyDelegation(userEntity, companyId); @@ -114,7 +114,8 @@ public class CompanyServiceImpl implements CompanyService { @Override @Transactional(rollbackFor = Exception.class) public void deleteCompanyDelegation(HttpServletRequest request, Long companyId) { - UserEntity userEntity =validator.validateUser(request); + + UserEntity userEntity = validator.validateUser(request); delegationDao.deleteCompanyDelegation(userEntity, companyId); } public UserWithCompanyEntity getUserWithCompanyEntity(Long userId,Long companyId){ diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/CompanyApiController.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/CompanyApiController.java index 55fd6cef..ef73e985 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/CompanyApiController.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/CompanyApiController.java @@ -4,6 +4,10 @@ import java.io.ByteArrayOutputStream; import java.util.List; import java.util.Map; +import net.gepafin.tendermanagement.enums.UserActionContextEnum; +import net.gepafin.tendermanagement.enums.UserActionLogsEnum; +import net.gepafin.tendermanagement.model.request.UserActionRequest; +import net.gepafin.tendermanagement.util.LoggingUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -30,71 +34,101 @@ import net.gepafin.tendermanagement.web.rest.api.errors.Status; @RestController @RequestMapping("${openapi.gepafin.base-path:/v1/company}") public class CompanyApiController implements CompanyApi{ - + private final Logger log = LoggerFactory.getLogger(CompanyApiController.class); - + @Autowired private CompanyService companyService; + @Autowired + private LoggingUtil loggingUtil; + @Override public ResponseEntity> createCompany(HttpServletRequest request, CompanyRequest companyRequest) { log.info("Create company with - Request Body: {}", companyRequest); + + /** This code is responsible for creating user action logs for "Creating company" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.INSERT).actionContext(UserActionContextEnum.CREATE_COMPANY).build()); + CompanyResponse data = companyService.createCompany(request, companyRequest); return ResponseEntity.status(HttpStatus.CREATED) .body(new Response<>(data, Status.SUCCESS, Translator.toLocale(GepafinConstant.COMPANY_CREATED_SUCCESS_MSG))); } - + @Override public ResponseEntity> updateCompany(HttpServletRequest request, Long companyId, CompanyRequest companyRequest) { log.info("Update company with - Request Body: {}", companyRequest); + + /** This code is responsible for creating user action logs for the "update company" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.UPDATE).actionContext(UserActionContextEnum.UPDATE_COMPANY).build()); + CompanyResponse data = companyService.updateCompany(request, companyId, companyRequest); - + return ResponseEntity.status(HttpStatus.OK) .body(new Response<>(data, Status.SUCCESS, Translator.toLocale(GepafinConstant.COMPANY_UPDATED_SUCCESS_MSG))); } - + @Override public ResponseEntity> getCompany(HttpServletRequest request, Long companyId) { - + log.info("Get company with id: {}", companyId); + + /** This code is responsible for creating user action logs for the "get company" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.VIEW).actionContext(UserActionContextEnum.GET_COMPANY).build()); + CompanyResponse data = companyService.getCompany(request, companyId); - - return ResponseEntity.status(HttpStatus.OK) - .body(new Response<>(data, Status.SUCCESS, Translator.toLocale(GepafinConstant.COMPANY_GET_SUCCESS_MSG))); + + return ResponseEntity.status(HttpStatus.OK).body(new Response<>(data, Status.SUCCESS, Translator.toLocale(GepafinConstant.COMPANY_GET_SUCCESS_MSG))); } - + @Override public ResponseEntity> deleteCompany(HttpServletRequest request, Long companyId) { log.info("Delete company with id: {}", companyId); + + /** This code is responsible for creating user action logs for the "delete company" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.DELETE).actionContext(UserActionContextEnum.DELETE_COMPANY).build()); + companyService.deleteCompany(request, companyId); - + return ResponseEntity.status(HttpStatus.OK) .body(new Response<>(null, Status.SUCCESS, Translator.toLocale(GepafinConstant.COMPANY_DELETE_SUCCESS_MSG))); } - + @Override public ResponseEntity>> getCompanyByUserId(HttpServletRequest request, Long userId) { log.info("Get company with userId: {}", userId); + + /** This code is responsible for creating user action logs for the "Get company by user id" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.VIEW).actionContext(UserActionContextEnum.GET_COMPANY_BY_USER).build()); + List data = companyService.getCompanyByUserId(request, userId); - + return ResponseEntity.status(HttpStatus.OK) .body(new Response<>(data, Status.SUCCESS, Translator.toLocale(GepafinConstant.COMPANY_GET_SUCCESS_MSG))); } - + @Override public ResponseEntity>> checkVatNumber(HttpServletRequest request, String vatNumber) { log.info("check VatNumber with: {}", vatNumber); + + /** This code is responsible for creating user action logs for the "Check vat number" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.VIEW).actionContext(UserActionContextEnum.CHECK_COMPANY_VAT_NUMBER).build()); + Map data = companyService.checkVatNumber(request, vatNumber); return ResponseEntity.status(HttpStatus.OK) .body(new Response<>(data, Status.SUCCESS, Translator.toLocale(GepafinConstant.CHECK_VATNUMBER_SUCCESS_MSG))); } - + @Override public ResponseEntity downloadCompanyDelegation(HttpServletRequest request, Long companyId, CompanyDelegationRequest companyDelegationRequest) { log.info("download company delegation with companyId: {}", companyId); + + /** This code is responsible for creating user action logs for the "Download company delegation" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.DOWNLOAD).actionContext(UserActionContextEnum.DOWNLOAD_COMPANY_DELEGATION_TEMPLATE).build()); + ByteArrayOutputStream data = companyService.downloadCompanyDelegation(request, companyId, companyDelegationRequest); HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_OCTET_STREAM); @@ -102,35 +136,51 @@ public class CompanyApiController implements CompanyApi{ return new ResponseEntity<>(data.toByteArray(), headers, HttpStatus.OK); } - + @Override public ResponseEntity> uploadCompanyDelegation(HttpServletRequest request, Long companyId, MultipartFile file) { log.info("upload company delegation with companyId: {}", companyId); + + /** This code is responsible for creating user action logs for the "Uploading company delegation document" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.UPLOAD).actionContext(UserActionContextEnum.UPLOAD_COMPANY_DELEGATION).build()); + CompanyDelegationResponse companyDelegationResponse = companyService.uploadCompanyDelegation(request, companyId, file); return ResponseEntity.status(HttpStatus.CREATED) .body(new Response<>(companyDelegationResponse, Status.SUCCESS, Translator.toLocale(GepafinConstant.DELEGATION_FILE_UPLOAD_SUCCESS))); } - + @Override public ResponseEntity> getCompanyDelegation(HttpServletRequest request, Long companyId) { log.info("get company delegation with companyId: {}", companyId); + + /** This code is responsible for creating user action logs for the "Get company delegation" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.VIEW).actionContext(UserActionContextEnum.GET_COMPANY_DELEGATION).build()); + CompanyDelegationResponse companyDelegationResponse = companyService.getCompanyDelegation(request, companyId); return ResponseEntity.status(HttpStatus.OK) .body(new Response<>(companyDelegationResponse, Status.SUCCESS, Translator.toLocale(GepafinConstant.DELEGATION_FETCH_SUCCESS))); } @Override - public ResponseEntity> deleteCompanyDelegation(HttpServletRequest request, - Long companyId) { + public ResponseEntity> deleteCompanyDelegation(HttpServletRequest request, Long companyId) { + log.info("delete company delegation with companyId: {}", companyId); + + /** This code is responsible for creating user action logs for the "delete company delegation" operation. **/ + loggingUtil.logUserAction( + UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.DELETE).actionContext(UserActionContextEnum.DELETE_COMPANY_DELEGATION).build()); + companyService.deleteCompanyDelegation(request, companyId); - return ResponseEntity.status(HttpStatus.OK) - .body(new Response<>(null, Status.SUCCESS, Translator.toLocale(GepafinConstant.DELEGATION_DELETE_SUCCESS))); + return ResponseEntity.status(HttpStatus.OK).body(new Response<>(null, Status.SUCCESS, Translator.toLocale(GepafinConstant.DELEGATION_DELETE_SUCCESS))); } @Override public ResponseEntity> removeCompanyFromList(HttpServletRequest request, Long companyId) { log.info("Api to remove a company from user's list"); + + /** This code is responsible for creating user action logs for the "Remove company from user list" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.DELETE).actionContext(UserActionContextEnum.REMOVE_COMPANY_FROM_USER).build()); + companyService.removeCompanyFromList(request, companyId); return ResponseEntity.status(HttpStatus.OK) From 5f5321c71ee90fd81202f8113586980a3357b6b5 Mon Sep 17 00:00:00 2001 From: piyushkag Date: Sun, 24 Nov 2024 20:48:08 +0530 Subject: [PATCH 19/43] Added user action and versioning for document. --- .../tendermanagement/dao/DocumentDao.java | 71 ++++++++++++++++++- .../enums/UserActionContextEnum.java | 12 +++- .../rest/api/impl/DocumentApiController.java | 38 ++++++++-- 3 files changed, 113 insertions(+), 8 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/DocumentDao.java b/src/main/java/net/gepafin/tendermanagement/dao/DocumentDao.java index 6f8e3243..3a6503a3 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/DocumentDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/DocumentDao.java @@ -2,9 +2,15 @@ package net.gepafin.tendermanagement.dao; import java.util.stream.Collectors; +import jakarta.servlet.http.HttpServletRequest; import lombok.extern.slf4j.Slf4j; import net.gepafin.tendermanagement.enums.DocumentSourceTypeEnum; +import net.gepafin.tendermanagement.enums.UserActionContextEnum; +import net.gepafin.tendermanagement.enums.VersionActionTypeEnum; +import net.gepafin.tendermanagement.model.request.VersionHistoryRequest; import net.gepafin.tendermanagement.repositories.ApplicationRepository; +import net.gepafin.tendermanagement.util.LoggingUtil; +import net.gepafin.tendermanagement.util.Utils; import net.gepafin.tendermanagement.web.rest.api.errors.CustomValidationException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -47,11 +53,18 @@ public class DocumentDao { @Autowired private ApplicationRepository applicationFormRepository; + + @Autowired + private LoggingUtil loggingUtil; + + @Autowired + private HttpServletRequest request; // @Value("${aws.s3.url.folder}") // private String s3Folder; public List uploadFiles(List files, Long sourceId, DocumentSourceTypeEnum sourceType, DocumentTypeEnum fileType) { + List documentEntities = new ArrayList<>(); Long source = resolveSourceId(sourceId, sourceType); for (MultipartFile file : files) { @@ -68,8 +81,44 @@ public class DocumentDao { } } documentRepository.saveAll(documentEntities); + + /** This code is responsible for adding a version history log for the "Upload call or application document based on source type" operation. **/ + + documentEntities.forEach(entity -> loggingUtil.addVersionHistory( + VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.INSERT).oldData(null).newData(entity).build())); + return documentEntities.stream().map(callDao::convertToDocumentResponseBean).collect(Collectors.toList()); } + + public UserActionContextEnum getUserActionContextEnum(DocumentSourceTypeEnum sourceType, DocumentTypeEnum fileType) { + + UserActionContextEnum userActionContext = null; + + if (fileType.equals(DocumentTypeEnum.DOCUMENT) && sourceType.equals(DocumentSourceTypeEnum.CALL)) { + userActionContext = UserActionContextEnum.UPLOAD_CALL_DOCUMENT; + } else if (fileType.equals(DocumentTypeEnum.IMAGES) && sourceType.equals(DocumentSourceTypeEnum.CALL)) { + userActionContext = UserActionContextEnum.UPLOAD_CALL_IMAGES; + } else if (fileType.equals(DocumentTypeEnum.DOCUMENT) && sourceType.equals(DocumentSourceTypeEnum.APPLICATION)) { + userActionContext = UserActionContextEnum.UPLOAD_APPLICATION_DOCUMENT; + } else if (fileType.equals(DocumentTypeEnum.IMAGES) && sourceType.equals(DocumentSourceTypeEnum.APPLICATION)) { + userActionContext = UserActionContextEnum.UPLOAD_APPLICATION_IMAGES; + } + + return userActionContext; + } + + public UserActionContextEnum getUserActionContextForUpdatingDocOrImage(DocumentTypeEnum documentTypeEnum) { + + UserActionContextEnum userActionContext; + + if (DocumentTypeEnum.DOCUMENT.equals(documentTypeEnum)) { + userActionContext = UserActionContextEnum.UPDATE_DOCUMENT; + } else{ + userActionContext = UserActionContextEnum.UPDATE_IMAGES; + } + return userActionContext; + } + private UploadFileOnAmazonS3Response uploadFileOnAmazonS3(MultipartFile file, DocumentSourceTypeEnum type, Long sourceId) { Long applicationId = 0L; @@ -109,11 +158,19 @@ public class DocumentDao { } public void deleteFile(Long documentId) { + DocumentEntity documentEntity = validateDocument(documentId); -// String fileName= Utils.extractFileName(documentEntity.getFilePath()); -// deleteFileOnAmazonS3(fileName); + //cloned for old data + DocumentEntity oldDocumentEntity = Utils.getClonedEntityForData(documentEntity); + + // String fileName= Utils.extractFileName(documentEntity.getFilePath()); + // deleteFileOnAmazonS3(fileName); documentEntity.setIsDeleted(true); documentRepository.save(documentEntity); + + /** This code is responsible for adding a version history log for the "Soft delete document" operation. **/ + loggingUtil.addVersionHistory( + VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.SOFT_DELETE).oldData(oldDocumentEntity).newData(documentEntity).build()); } @@ -123,16 +180,24 @@ public class DocumentDao { } public DocumentResponseBean updateDocument(Long documentId, MultipartFile file, DocumentTypeEnum documentTypeEnum) { + DocumentEntity documentEntity = validateDocument(documentId); + //cloned entity for old data + DocumentEntity oldDocumentData = Utils.getClonedEntityForData(documentEntity); + String type = documentEntity.getSource(); UploadFileOnAmazonS3Response uploadFileOnAmazonS3Response = updateFileOnAmazonS3(file, DocumentSourceTypeEnum.valueOf(type), documentEntity.getSourceId()); - if (uploadFileOnAmazonS3Response != null) { + if (uploadFileOnAmazonS3Response != null) { documentEntity.setFileName(uploadFileOnAmazonS3Response.getFileName()); documentEntity.setFilePath(uploadFileOnAmazonS3Response.getFilePath()); documentEntity.setType(documentTypeEnum.getValue()); documentEntity.setSource(documentEntity.getSource()); documentEntity.setSourceId(documentEntity.getSourceId()); documentRepository.save(documentEntity); + + /** This code is responsible for adding a version history log for the "updating doc or image" operation. **/ + loggingUtil.addVersionHistory( + VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldDocumentData).newData(documentEntity).build()); } return callDao.convertToDocumentResponseBean(documentEntity); } diff --git a/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java index 7a694931..868a6e5b 100644 --- a/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java +++ b/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java @@ -88,7 +88,17 @@ public enum UserActionContextEnum { CREATE_ASSIGNED_APPLICATION("CREATE_ASSIGNED_APPLICATION"), DELETE_ASSIGNED_APPLICATION("DELETE_ASSIGNED_APPLICATION"), GET_ASSIGNED_APPLICATION("GET_ASSIGNED_APPLICATION"), - UPDATE_ASSIGNED_APPLICATION_DETAILS("UPDATE_ASSIGNED_APPLICATION_DETAILS"); + UPDATE_ASSIGNED_APPLICATION_DETAILS("UPDATE_ASSIGNED_APPLICATION_DETAILS"), + + /** Document action context **/ + UPLOAD_CALL_DOCUMENT("UPLOAD_CALL_DOCUMENT"), + UPLOAD_CALL_IMAGES("UPLOAD_CALL_IMAGES"), + UPLOAD_APPLICATION_DOCUMENT("UPLOAD_APPLICATION_DOCUMENT"), + UPLOAD_APPLICATION_IMAGES("UPLOAD_APPLICATION_IMAGES"), + DELETE_DOCUMENT("DELETE_DOCUMENT"), + UPDATE_DOCUMENT("UPDATE_DOCUEMENT"), + UPDATE_IMAGES("UPDATE_IMAGES"), + GET_DOCUMENT("GET_DOCUMENT"); private final String value; diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/DocumentApiController.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/DocumentApiController.java index 34caa9fd..9d42ab53 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/DocumentApiController.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/DocumentApiController.java @@ -3,11 +3,16 @@ 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.dao.DocumentDao; import net.gepafin.tendermanagement.enums.DocumentSourceTypeEnum; import net.gepafin.tendermanagement.enums.DocumentTypeEnum; +import net.gepafin.tendermanagement.enums.UserActionContextEnum; +import net.gepafin.tendermanagement.enums.UserActionLogsEnum; +import net.gepafin.tendermanagement.model.request.UserActionRequest; import net.gepafin.tendermanagement.model.response.DocumentResponseBean; import net.gepafin.tendermanagement.model.util.Response; import net.gepafin.tendermanagement.service.DocumentService; +import net.gepafin.tendermanagement.util.LoggingUtil; import net.gepafin.tendermanagement.web.rest.api.DocumentApi; import net.gepafin.tendermanagement.web.rest.api.errors.CustomValidationException; import net.gepafin.tendermanagement.web.rest.api.errors.Status; @@ -27,10 +32,21 @@ DocumentApiController implements DocumentApi { @Autowired private DocumentService documentService; + @Autowired + private LoggingUtil loggingUtil; + + @Autowired + private DocumentDao documentDao; + @Override public ResponseEntity>> uploadFile(HttpServletRequest httpServletRequest, Long sourceId, DocumentSourceTypeEnum sourceType, List files, DocumentTypeEnum fileType) { try { + UserActionContextEnum userActionContext = documentDao.getUserActionContextEnum(sourceType, fileType); + + /** This code is responsible for creating user action logs for the "upload document for call or application" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(httpServletRequest).actionType(UserActionLogsEnum.UPLOAD).actionContext(userActionContext).build()); + List responseBeans = documentService.uploadFile(files, sourceId, sourceType, fileType); return ResponseEntity.status(HttpStatus.CREATED) .body(new Response>(responseBeans, Status.SUCCESS, Translator.toLocale(GepafinConstant.FILES_UPLOADED_MSG))); @@ -40,6 +56,10 @@ DocumentApiController implements DocumentApi { } @Override public ResponseEntity> deleteFile(HttpServletRequest httpServletRequest, Long documentId) { + + /** This code is responsible for creating user action logs for the "delete document" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(httpServletRequest).actionType(UserActionLogsEnum.DELETE).actionContext(UserActionContextEnum.DELETE_DOCUMENT).build()); + documentService.deleteFile(documentId); return ResponseEntity.status(HttpStatus.CREATED) .body(new Response(null, Status.SUCCESS, Translator.toLocale(GepafinConstant.FILE_DELETED_SUCCESSFULLY_MSG))); @@ -47,6 +67,12 @@ DocumentApiController implements DocumentApi { @Override public ResponseEntity> updateDocument(HttpServletRequest httpServletRequest, Long documentId, MultipartFile file, DocumentTypeEnum documentTypeEnum) { + + UserActionContextEnum userActionContext = documentDao.getUserActionContextForUpdatingDocOrImage(documentTypeEnum); + + /** This code is responsible for creating user action logs for the "update document or image" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(httpServletRequest).actionType(UserActionLogsEnum.UPDATE).actionContext(userActionContext).build()); + DocumentResponseBean responseBeans = documentService.updateDocument(httpServletRequest, documentId, file, documentTypeEnum); return ResponseEntity.status(HttpStatus.CREATED) .body(new Response(responseBeans, Status.SUCCESS, Translator.toLocale(GepafinConstant.DOCUMENT_UPDATED_SUCCESSFULLY))); @@ -54,8 +80,12 @@ DocumentApiController implements DocumentApi { @Override public ResponseEntity> getDocumentById(HttpServletRequest request, Long id) { - DocumentResponseBean documentResponseBean= documentService.getDocument(request,id); - return ResponseEntity.status(HttpStatus.CREATED) - .body(new Response(documentResponseBean, Status.SUCCESS, Translator.toLocale(GepafinConstant.DOCUMENT_FETCHED_SUCCESSFULLY))); -} + + /** This code is responsible for creating user action logs for the "Get Document" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.VIEW).actionContext(UserActionContextEnum.GET_DOCUMENT).build()); + + DocumentResponseBean documentResponseBean = documentService.getDocument(request, id); + return ResponseEntity.status(HttpStatus.CREATED) + .body(new Response(documentResponseBean, Status.SUCCESS, Translator.toLocale(GepafinConstant.DOCUMENT_FETCHED_SUCCESSFULLY))); + } } \ No newline at end of file From 64919a455c845423cce8b485a86115e3c46c366f Mon Sep 17 00:00:00 2001 From: piyushkag Date: Sun, 24 Nov 2024 21:29:32 +0530 Subject: [PATCH 20/43] Added user action and versioning for login attempt. --- .../tendermanagement/dao/LoginAttemptDao.java | 12 +++--------- .../enums/UserActionContextEnum.java | 6 +++++- .../rest/api/impl/LoginAttemptApiController.java | 15 +++++++++++++++ 3 files changed, 23 insertions(+), 10 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/LoginAttemptDao.java b/src/main/java/net/gepafin/tendermanagement/dao/LoginAttemptDao.java index a4629584..75bbdde5 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/LoginAttemptDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/LoginAttemptDao.java @@ -38,18 +38,12 @@ public class LoginAttemptDao { public LoginAttemptEntity createLoginAttempt(LoginAttemptEntity loginAttemptEntity) { VersionActionTypeEnum actionType; - LoginAttemptEntity oldLoginAttemptEntity = Utils.getClonedEntityForData(loginAttemptEntity); loginAttemptEntity.setAttemptDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); - if(loginAttemptEntity.getId() != null ) { - actionType = VersionActionTypeEnum.UPDATE; - }else{ - actionType = VersionActionTypeEnum.INSERT; - oldLoginAttemptEntity = null; - } - loginAttemptEntity = loginAttemptRepository.save(loginAttemptEntity); + loginAttemptEntity = loginAttemptRepository.save(loginAttemptEntity); /** This code is responsible for adding a version history log for "Create Login Attempt" operation. **/ - loggingUtil.addVersionHistoryWithoutToken(VersionHistoryRequest.builder().actionType(actionType).request(request).oldData(oldLoginAttemptEntity).newData(loginAttemptEntity).build()); + loggingUtil.addVersionHistoryWithoutToken( + VersionHistoryRequest.builder().actionType(VersionActionTypeEnum.INSERT).request(request).oldData(null).newData(loginAttemptEntity).build()); return loginAttemptEntity; } diff --git a/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java index 868a6e5b..6987ae0f 100644 --- a/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java +++ b/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java @@ -98,7 +98,11 @@ public enum UserActionContextEnum { DELETE_DOCUMENT("DELETE_DOCUMENT"), UPDATE_DOCUMENT("UPDATE_DOCUEMENT"), UPDATE_IMAGES("UPDATE_IMAGES"), - GET_DOCUMENT("GET_DOCUMENT"); + GET_DOCUMENT("GET_DOCUMENT"), + + /** Login attempt action context **/ + GET_LOGIN_ATTEMPT_LIST("GET_LOGIN_ATTEMPT_LIST"), + ADD_LOGIN_ATTEMPT("ADD_LOGIN_ATTEMPT"); private final String value; diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/LoginAttemptApiController.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/LoginAttemptApiController.java index cfd601b3..e28cf4a7 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/LoginAttemptApiController.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/LoginAttemptApiController.java @@ -5,11 +5,15 @@ import net.gepafin.tendermanagement.config.Translator; import net.gepafin.tendermanagement.constants.GepafinConstant; import net.gepafin.tendermanagement.entities.LoginAttemptEntity; import net.gepafin.tendermanagement.entities.UserEntity; +import net.gepafin.tendermanagement.enums.UserActionContextEnum; +import net.gepafin.tendermanagement.enums.UserActionLogsEnum; import net.gepafin.tendermanagement.model.request.LoginAttemptReq; +import net.gepafin.tendermanagement.model.request.UserActionRequest; import net.gepafin.tendermanagement.model.response.LoginAttemptPageableResponseBean; import net.gepafin.tendermanagement.model.util.Response; import net.gepafin.tendermanagement.service.LoginAttemptService; import net.gepafin.tendermanagement.service.UserService; +import net.gepafin.tendermanagement.util.LoggingUtil; import net.gepafin.tendermanagement.util.Validator; import net.gepafin.tendermanagement.web.rest.api.LoginAttemptApi; import net.gepafin.tendermanagement.web.rest.api.errors.Status; @@ -38,8 +42,15 @@ public class LoginAttemptApiController implements LoginAttemptApi { @Autowired private UserService userService; + @Autowired + private LoggingUtil loggingUtil; + @Override public ResponseEntity>> getLoginAttemptsList(HttpServletRequest request, Integer pageNo, Integer pageLimit) { + + /** This code is responsible for creating user action logs for the "Get login attempt list" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.VIEW).actionContext(UserActionContextEnum.GET_LOGIN_ATTEMPT_LIST).build()); + LoginAttemptPageableResponseBean> response = loginAttemptService.getLoginAttemptsList(request, pageNo, pageLimit); return ResponseEntity.status(HttpStatus.OK).body(response); } @@ -50,6 +61,10 @@ public class LoginAttemptApiController implements LoginAttemptApi { String userIdString = (String) userInfo.get("userId"); UserEntity currentUser = userService.getUserEntityById(Long.parseLong(userIdString)); loginAttemptReq.setUserName(currentUser.getEmail()); + + /** This code is responsible for creating user action logs for the "add login attempt" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.INSERT).actionContext(UserActionContextEnum.ADD_LOGIN_ATTEMPT).build()); + loginAttemptService.createLoginAttempt(loginAttemptReq, request); return ResponseEntity.status(HttpStatus.CREATED).body(new Response(null, Status.SUCCESS, Translator.toLocale(GepafinConstant.LOGIN_ATTEMPTED_CREATED_SUCCESSFULLY))); } From 580167e93270b0fac626f722f61517eb0df44f37 Mon Sep 17 00:00:00 2001 From: rajesh Date: Sun, 24 Nov 2024 21:37:32 +0530 Subject: [PATCH 21/43] Added user action and versioning for Form field controller --- .../tendermanagement/dao/FormFieldDao.java | 39 ++++++++++++++++--- .../enums/UserActionContextEnum.java | 6 +++ .../rest/api/impl/FormFieldApiController.java | 32 +++++++++++++++ 3 files changed, 71 insertions(+), 6 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/FormFieldDao.java b/src/main/java/net/gepafin/tendermanagement/dao/FormFieldDao.java index 57f67694..d2d3cef6 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/FormFieldDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/FormFieldDao.java @@ -3,12 +3,15 @@ package net.gepafin.tendermanagement.dao; import net.gepafin.tendermanagement.config.Translator; import net.gepafin.tendermanagement.constants.GepafinConstant; import net.gepafin.tendermanagement.entities.FormFieldEntity; +import net.gepafin.tendermanagement.enums.VersionActionTypeEnum; import net.gepafin.tendermanagement.model.request.FormFieldRequest; import net.gepafin.tendermanagement.model.request.SettingRequestBean; +import net.gepafin.tendermanagement.model.request.VersionHistoryRequest; import net.gepafin.tendermanagement.model.response.FormFieldResponseBean; import net.gepafin.tendermanagement.model.response.SettingResponseBean; import net.gepafin.tendermanagement.repositories.FormFieldRepository; import net.gepafin.tendermanagement.util.DateTimeUtil; +import net.gepafin.tendermanagement.util.LoggingUtil; import net.gepafin.tendermanagement.util.Utils; import net.gepafin.tendermanagement.web.rest.api.errors.CustomValidationException; import net.gepafin.tendermanagement.web.rest.api.errors.ResourceNotFoundException; @@ -16,6 +19,8 @@ import net.gepafin.tendermanagement.web.rest.api.errors.Status; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import jakarta.servlet.http.HttpServletRequest; + import java.time.LocalDateTime; import java.util.List; import java.util.stream.Collectors; @@ -25,6 +30,12 @@ public class FormFieldDao { @Autowired private FormFieldRepository formFieldRepository; + + @Autowired + private LoggingUtil loggingUtil; + + @Autowired + private HttpServletRequest request; public FormFieldEntity convertFormFieldRequestToFormFieldEntity(FormFieldRequest formFieldRequest) { FormFieldEntity formFieldEntity = new FormFieldEntity(); @@ -34,7 +45,11 @@ public class FormFieldDao { formFieldEntity.setSortOrder(formFieldRequest.getSortOrder()); formFieldEntity.setValidators(Utils.convertMapIntoJsonString(formFieldRequest.getValidators())); formFieldEntity.setSettings(setSettingRequestBean(formFieldRequest.getSettings())); - formFieldEntity = saveFormFieldEntity(formFieldEntity); + formFieldEntity = formFieldRepository.save(formFieldEntity); + + /** This code is responsible for adding a version history log for the "Create FormField" operation. **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.INSERT).oldData(null).newData(formFieldEntity).build()); + return formFieldEntity; } @@ -51,10 +66,10 @@ public class FormFieldDao { return formFieldResponseBean; } - public FormFieldEntity saveFormFieldEntity(FormFieldEntity formFieldEntity) { - formFieldEntity = formFieldRepository.save(formFieldEntity); - return formFieldEntity; - } +// public FormFieldEntity saveFormFieldEntity(FormFieldEntity formFieldEntity) { +// formFieldEntity = formFieldRepository.save(formFieldEntity); +// return formFieldEntity; +// } public void validateFormField(FormFieldRequest formFieldRequest) { if (formFieldRequest.getSettings() == null || formFieldRequest.getLabel() == null) { @@ -71,6 +86,7 @@ public class FormFieldDao { public FormFieldResponseBean updateFormField(Long formFieldId, FormFieldRequest formFieldRequest) { FormFieldEntity formFieldEntity = validateFormField(formFieldId); + FormFieldEntity oldFormFieldEntity = Utils.getClonedEntityForData(formFieldEntity); Utils.setIfUpdated(formFieldEntity::getName, formFieldEntity::setName, formFieldRequest.getName()); Utils.setIfUpdated(formFieldEntity::getLabel, formFieldEntity::setLabel, formFieldRequest.getLabel()); Utils.setIfUpdated(formFieldEntity::getDescription, formFieldEntity::setDescription, formFieldRequest.getDescription()); @@ -80,7 +96,13 @@ public class FormFieldDao { Utils.setIfUpdated(formFieldEntity::getValidators, formFieldEntity::setValidators, Utils.convertMapIntoJsonString(formFieldRequest.getValidators())); formFieldEntity.setUpdatedDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); - formFieldEntity = saveFormFieldEntity(formFieldEntity); + + formFieldEntity = formFieldRepository.save(formFieldEntity); + + /** This code is responsible for adding a version history log for the "Update FormField" operation. **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldFormFieldEntity).newData(formFieldEntity).build()); + + return convertFormFieldEntityToFormFieldResponseBean(formFieldEntity); } @@ -99,6 +121,11 @@ public class FormFieldDao { public void deleteFormById(Long formFieldId) { FormFieldEntity formEntity = validateFormField(formFieldId); formFieldRepository.delete(formEntity); + + /** This code is responsible for adding a version history log for the "Delete FormField" operation. **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.DELETE).oldData(formEntity).newData(null).build()); + + } public String setSettingRequestBean(List settingRequestBeans) { diff --git a/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java index 868a6e5b..d452fd32 100644 --- a/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java +++ b/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java @@ -89,6 +89,12 @@ public enum UserActionContextEnum { DELETE_ASSIGNED_APPLICATION("DELETE_ASSIGNED_APPLICATION"), GET_ASSIGNED_APPLICATION("GET_ASSIGNED_APPLICATION"), UPDATE_ASSIGNED_APPLICATION_DETAILS("UPDATE_ASSIGNED_APPLICATION_DETAILS"), + + /** Assigned form field context **/ + CREATE_FORM_FIELD("CREATE_FORM_FIELD"), + UPDATE_FORM_FIELD("UPDATE_FORM_FIELD"), + GET_FORM_FIELD("GET_FORM_FIELD"), + DELETE_FORM_FIELD("DELETE_FORM_FIELD"), /** Document action context **/ UPLOAD_CALL_DOCUMENT("UPLOAD_CALL_DOCUMENT"), diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/FormFieldApiController.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/FormFieldApiController.java index e491d498..485d9387 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/FormFieldApiController.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/FormFieldApiController.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.FormFieldRequest; +import net.gepafin.tendermanagement.model.request.UserActionRequest; import net.gepafin.tendermanagement.model.response.FormFieldResponseBean; import net.gepafin.tendermanagement.model.util.Response; import net.gepafin.tendermanagement.service.FormFieldService; +import net.gepafin.tendermanagement.util.LoggingUtil; import net.gepafin.tendermanagement.web.rest.api.FormFieldApi; import net.gepafin.tendermanagement.web.rest.api.errors.Status; import org.springframework.beans.factory.annotation.Autowired; @@ -23,9 +27,17 @@ public class FormFieldApiController implements FormFieldApi { @Autowired private FormFieldService formFieldService; + + @Autowired + private LoggingUtil loggingUtil; @Override public ResponseEntity> createFormField(HttpServletRequest request, FormFieldRequest formFieldRequest) { + + /** This code is responsible for creating user action logs for the "Create Form field" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.INSERT) + .actionContext(UserActionContextEnum.CREATE_FORM_FIELD).build()); + FormFieldResponseBean formFieldResponseBean=formFieldService.createFormField(request,formFieldRequest); return ResponseEntity.status(HttpStatus.CREATED) .body(new Response<>(formFieldResponseBean, Status.SUCCESS, Translator.toLocale(GepafinConstant.FORM_FIELD_CREATED_SUCCESSFULLY))); @@ -33,6 +45,11 @@ public class FormFieldApiController implements FormFieldApi { @Override public ResponseEntity> updateFormField(HttpServletRequest request, Long formFieldId, FormFieldRequest formFieldRequest) { + + /** This code is responsible for creating user action logs for the "Update Form field" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.UPDATE) + .actionContext(UserActionContextEnum.UPDATE_FORM_FIELD).build()); + FormFieldResponseBean formFieldResponseBean=formFieldService.updateFormField(request,formFieldId,formFieldRequest); return ResponseEntity.status(HttpStatus.CREATED) .body(new Response<>(formFieldResponseBean, Status.SUCCESS, Translator.toLocale(GepafinConstant.FORM_FIELD_UPDATED_SUCCESSFULLY))); @@ -40,6 +57,11 @@ public class FormFieldApiController implements FormFieldApi { @Override public ResponseEntity> getFormFieldById(HttpServletRequest request, Long formFieldId) { + + /** This code is responsible for creating user action logs for the "Get Form field" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.VIEW) + .actionContext(UserActionContextEnum.GET_FORM_FIELD).build()); + FormFieldResponseBean formFieldResponseBean=formFieldService.getFormFieldById(request,formFieldId); return ResponseEntity.status(HttpStatus.OK) .body(new Response<>(formFieldResponseBean, Status.SUCCESS, Translator.toLocale(GepafinConstant.FORM_FIELD_FETCHED_SUCCESSFULLY))); @@ -47,6 +69,11 @@ public class FormFieldApiController implements FormFieldApi { @Override public ResponseEntity> deleteForm(HttpServletRequest request, Long formFieldId) { + + /** This code is responsible for creating user action logs for the "Get Form field" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.DELETE) + .actionContext(UserActionContextEnum.DELETE_FORM_FIELD).build()); + formFieldService.deleteFormField(request,formFieldId); return ResponseEntity.status(HttpStatus.OK) .body(new Response<>(null, Status.SUCCESS, Translator.toLocale(GepafinConstant.FORM_FIELD_DELETED_SUCCESSFULLY))); @@ -54,6 +81,11 @@ public class FormFieldApiController implements FormFieldApi { @Override public ResponseEntity>> getAllFormField(HttpServletRequest request) { + + /** This code is responsible for creating user action logs for the "Get all Form field" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.VIEW) + .actionContext(UserActionContextEnum.GET_FORM_FIELD).build()); + List formFieldResponseBeans=formFieldService.getAllFormField(request); return ResponseEntity.status(HttpStatus.OK) .body(new Response<>(formFieldResponseBeans, Status.SUCCESS, Translator.toLocale(GepafinConstant.FORM_FIELD_FETCHED_SUCCESSFULLY))); From 5143795b3695df19bf8750119b1f44f6ac9e2350 Mon Sep 17 00:00:00 2001 From: rajesh Date: Sun, 24 Nov 2024 21:58:11 +0530 Subject: [PATCH 22/43] Added user action and versioning for Flow get api --- .../enums/UserActionContextEnum.java | 4 ++++ .../web/rest/api/impl/FlowApiController.java | 21 +++++++++++++++++-- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java index ac171abb..9d69bf7f 100644 --- a/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java +++ b/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java @@ -105,6 +105,10 @@ public enum UserActionContextEnum { UPDATE_DOCUMENT("UPDATE_DOCUEMENT"), UPDATE_IMAGES("UPDATE_IMAGES"), GET_DOCUMENT("GET_DOCUMENT"), + + /** Assigned flow context **/ + CREATE_UPDATE_FLOW("CREATE_UPDATE_FLOW"), + GET_FLOW("GET_FLOW"), /** Login attempt action context **/ GET_LOGIN_ATTEMPT_LIST("GET_LOGIN_ATTEMPT_LIST"), diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/FlowApiController.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/FlowApiController.java index 68cb183b..11fc5aad 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/FlowApiController.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/FlowApiController.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.FlowRequestBean; +import net.gepafin.tendermanagement.model.request.UserActionRequest; import net.gepafin.tendermanagement.model.response.FlowResponseBean; import net.gepafin.tendermanagement.model.util.Response; import net.gepafin.tendermanagement.service.FlowService; +import net.gepafin.tendermanagement.util.LoggingUtil; import net.gepafin.tendermanagement.web.rest.api.FlowApi; import net.gepafin.tendermanagement.web.rest.api.errors.Status; import org.springframework.beans.factory.annotation.Autowired; @@ -22,16 +26,29 @@ public class FlowApiController implements FlowApi { @Autowired private FlowService flowService; + + @Autowired + private LoggingUtil loggingUtil; @Override - public ResponseEntity> createOrUpdateFlow(HttpServletRequest httpServletRequest, FlowRequestBean flowRequestBean, Long callId) { - FlowResponseBean flowResponseBean=flowService.createOrUpdateFlow(httpServletRequest,flowRequestBean,callId); + public ResponseEntity> createOrUpdateFlow(HttpServletRequest request, FlowRequestBean flowRequestBean, Long callId) { + + /** This code is responsible for creating user action logs for the "Create or update Flow" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.INSERT) + .actionContext(UserActionContextEnum.CREATE_UPDATE_FLOW).build()); + + FlowResponseBean flowResponseBean=flowService.createOrUpdateFlow(request,flowRequestBean,callId); return ResponseEntity.status(HttpStatus.CREATED) .body(new Response<>(flowResponseBean, Status.SUCCESS, Translator.toLocale(GepafinConstant.FLOW_CREATED_SUCCESSFULLY))); } @Override public ResponseEntity> getFlowByCallId(HttpServletRequest request, Long callId) { + + /** This code is responsible for creating user action logs for the "Create or update Flow" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.VIEW) + .actionContext(UserActionContextEnum.GET_FLOW).build()); + FlowResponseBean flowResponseBean=flowService.getFlowByCallId(request,callId); return ResponseEntity.status(HttpStatus.OK) .body(new Response<>(flowResponseBean, Status.SUCCESS, Translator.toLocale(GepafinConstant.FLOW_FETCHED_SUCCESSFULLY))); From ff7b4efc3d365f9e26f8255dce52543a81cf9303 Mon Sep 17 00:00:00 2001 From: piyushkag Date: Sun, 24 Nov 2024 22:00:15 +0530 Subject: [PATCH 23/43] Added user action for Dashbaord. --- .../enums/UserActionContextEnum.java | 6 +++++- .../web/rest/api/impl/DashboardApiController.java | 15 +++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java index 6987ae0f..fbee7cf3 100644 --- a/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java +++ b/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java @@ -102,7 +102,11 @@ public enum UserActionContextEnum { /** Login attempt action context **/ GET_LOGIN_ATTEMPT_LIST("GET_LOGIN_ATTEMPT_LIST"), - ADD_LOGIN_ATTEMPT("ADD_LOGIN_ATTEMPT"); + ADD_LOGIN_ATTEMPT("ADD_LOGIN_ATTEMPT"), + + /** Dashboard action context **/ + GET_DASHBOARD_WIDGET_FOR_SUPER_ADMIN("GET_DASHBOARD_WIDGET_FOR_SUPER_ADMIN"), + GET_DASHBOARD_WIDGET_FOR_BENEFICIARY("GET_DASHBOARD_WIDGET_FOR_BENEFICIARY"); private final String value; diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/DashboardApiController.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/DashboardApiController.java index c46258a2..7ff7be61 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/DashboardApiController.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/DashboardApiController.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.UserActionRequest; import net.gepafin.tendermanagement.model.response.BeneficiaryWidgetResponseBean; import net.gepafin.tendermanagement.model.response.SuperAdminWidgetResponseBean; import net.gepafin.tendermanagement.model.util.Response; import net.gepafin.tendermanagement.service.DashboardService; +import net.gepafin.tendermanagement.util.LoggingUtil; import net.gepafin.tendermanagement.web.rest.api.DashboardApi; import net.gepafin.tendermanagement.web.rest.api.errors.Status; import org.springframework.beans.factory.annotation.Autowired; @@ -22,14 +26,25 @@ public class DashboardApiController implements DashboardApi { @Autowired private DashboardService dashboardService; + @Autowired + private LoggingUtil loggingUtil; + @Override public ResponseEntity> getDashboardWidgetForSuperAdmin(HttpServletRequest request) { + + /** This code is responsible for creating user action logs for the "Get dashboard widget for super admin" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.VIEW).actionContext(UserActionContextEnum.GET_DASHBOARD_WIDGET_FOR_SUPER_ADMIN).build()); + SuperAdminWidgetResponseBean widgetResponseBean= dashboardService.getDashboardWidgetForSuperAdmin(request); return ResponseEntity.status(HttpStatus.CREATED) .body(new Response<>(widgetResponseBean, Status.SUCCESS, Translator.toLocale(GepafinConstant.DASHBOARD_WIDGET_FETCHED_SUCCESSFULLY))); } @Override public ResponseEntity> getDashboardWidgetForBeneficiary(HttpServletRequest request, Long companyId) { + + /** This code is responsible for creating user action logs for the "Get dashboard widget for beneficiary" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.VIEW).actionContext(UserActionContextEnum.GET_DASHBOARD_WIDGET_FOR_BENEFICIARY).build()); + BeneficiaryWidgetResponseBean widgetResponseBean= dashboardService.getDashboardWidgetForBeneficiary(request, companyId); return ResponseEntity.status(HttpStatus.CREATED) .body(new Response<>(widgetResponseBean, Status.SUCCESS, Translator.toLocale(GepafinConstant.DASHBOARD_WIDGET_FETCHED_SUCCESSFULLY))); From 36725d3d46263b02c1ef4007dbbf441b94653d45 Mon Sep 17 00:00:00 2001 From: nisha Date: Sun, 24 Nov 2024 23:52:51 +0530 Subject: [PATCH 24/43] Done ticket GEPAFINBE-90 --- .../constants/GepafinConstant.java | 2 + .../dao/ApplicationAmendmentRequestDao.java | 58 +++++++++++++++++-- .../dao/ApplicationEvaluationDao.java | 19 ++++-- .../ApplicationAmendmentRequestEntity.java | 3 + .../entities/ApplicationEvaluationEntity.java | 21 ++++++- .../ApplicationEvaluationStatusTypeEnum.java | 1 + .../ApplicationAmendmentRequestResponse.java | 1 + .../ApplicationEvaluationResponse.java | 2 +- ...ApplicationAmendmentRequestRepository.java | 17 ++++++ .../ApplicationEvaluationRepository.java | 4 +- .../ApplicationEvaluationScheduler.java | 29 ++++++++++ .../scheduler/NotificationScheduler.java | 31 +++++++--- .../db/changelog/db.changelog-1.0.0.xml | 16 +++++ src/main/resources/message_en.properties | 3 + src/main/resources/message_it.properties | 2 + 15 files changed, 186 insertions(+), 23 deletions(-) create mode 100644 src/main/java/net/gepafin/tendermanagement/scheduler/ApplicationEvaluationScheduler.java diff --git a/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java b/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java index 272d3f23..9d477c37 100644 --- a/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java +++ b/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java @@ -294,5 +294,7 @@ public class GepafinConstant { public static final String DUPLICATE_BENEFICIARY_CALL = "beneficiary.call.duplicate"; public static final String COMPANY_ID_REQUIRED_FOR_PREFERRED_CALL = "company.id.required.for.preferred.call"; public static final String CREATED_DATE = "createdDate"; + public static final String RESPONSE_DAYS_NOT_NULL="response.days.not.null"; + public static final String APPLICATION_CANNOT_APPROVED_OR_REJECTED="application.cannot.approved.or.rejected"; } diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java index a4da3b00..c646c73b 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java @@ -31,6 +31,7 @@ import java.time.temporal.ChronoUnit; import java.util.*; import java.util.stream.Collectors; +import static java.time.temporal.ChronoUnit.DAYS; import static net.gepafin.tendermanagement.util.Utils.log; import static net.gepafin.tendermanagement.util.Utils.setIfUpdated; @@ -97,6 +98,9 @@ public class ApplicationAmendmentRequestDao { @Autowired private EmailLogDao emailLogDao; + @Autowired + private ApplicationAmendmentRequestDao applicationAmendmentRequestDao; + public ApplicationAmendmentRequestResponse getApplicationDataForAmendment(Long applicationEvaluationId) { log.info("Fetching the application data for the Amendment process {}", applicationEvaluationId); ApplicationEvaluationEntity applicationEvaluationEntity = applicationEvaluationService.validateApplicationEvaluation(applicationEvaluationId); @@ -204,6 +208,11 @@ public class ApplicationAmendmentRequestDao { ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity = new ApplicationAmendmentRequestEntity(); applicationAmendmentRequestEntity.setNote(applicationAmendmentRequest.getNote()); applicationAmendmentRequestEntity.setResponseDays(applicationAmendmentRequest.getResponseDays()); + if(applicationAmendmentRequest.getResponseDays()==null && applicationAmendmentRequest.getResponseDays() < 0){ + throw new CustomValidationException(Status.BAD_REQUEST,Translator.toLocale(GepafinConstant.RESPONSE_DAYS_NOT_NULL)); + } + applicationAmendmentRequestEntity.setEndDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now()).plusDays(applicationAmendmentRequest.getResponseDays())); + applicationAmendmentRequestEntity.setIsEmail(applicationAmendmentRequest.getIsSendEmail()); applicationAmendmentRequestEntity.setIsNotification(applicationAmendmentRequest.getIsSendNotification()); applicationAmendmentRequestEntity.setStartDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); @@ -228,6 +237,20 @@ public class ApplicationAmendmentRequestDao { String formFieldsJson = Utils.convertObjectToJson(formFieldRequestBean); applicationAmendmentRequestEntity.setFormFields(formFieldsJson); } + List amendmentRequest = applicationAmendmentRequestRepository.findAllByApplicationEvaluationIdAndIsDeletedFalse(applicationEvaluationEntity.getId()); + // Ensure startDate and initialDays are not null to avoid NullPointerException + if (amendmentRequest !=null && amendmentRequest.isEmpty() && applicationEvaluationEntity.getStartDate() != null && applicationEvaluationEntity.getInitialDays() != null ) { + Long initialDays = applicationEvaluationEntity.getInitialDays(); + LocalDateTime startDate = applicationEvaluationEntity.getStartDate(); + LocalDateTime nowInUTC = DateTimeUtil.DateServerToUTC(LocalDateTime.now()); + // Calculate remaining days + Long remainingDays = initialDays - DAYS.between(startDate, nowInUTC); + // Set remaining days in the entity + applicationEvaluationEntity.setRemainingDays(remainingDays); + //Set stop date time in the entity becuase amendment has started + applicationEvaluationEntity.setStopDateTime(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); + } + UserEntity userEntity = userService.validateUser(applicationEvaluationEntity.getUserId()); Long protocolNumber = protocolDao.getProtocolNumber(userEntity.getHub()); ProtocolEntity protocolEntity = protocolDao.createProtocolEntity( @@ -238,6 +261,7 @@ public class ApplicationAmendmentRequestDao { //Set Status applicationEvaluationEntity.setStatus(ApplicationEvaluationStatusTypeEnum.SOCCORSO.getValue()); + applicationEvaluationRepository.save(applicationEvaluationEntity); ApplicationEntity applicationEntity = applicationService.validateApplication(applicationId); @@ -271,10 +295,8 @@ public class ApplicationAmendmentRequestDao { applicationAmendmentRequestResponse.setInternalNote(applicationAmendmentRequestEntity.getInternalNote()); LocalDateTime startDate = applicationAmendmentRequestEntity.getStartDate(); applicationAmendmentRequestResponse.setStartDate(startDate); - - LocalDateTime expirationDate = startDate.plus(expirationDays, ChronoUnit.DAYS); - applicationAmendmentRequestResponse.setExpirationDate(expirationDate); - + applicationAmendmentRequestResponse.setExpirationDate(applicationAmendmentRequestEntity.getEndDate()); + applicationAmendmentRequestResponse.setEvaluationEndDate(applicationAmendmentRequestEntity.getApplicationEvaluationEntity().getEndDate()); applicationAmendmentRequestResponse.setIsSendEmail(applicationAmendmentRequestEntity.getIsEmail()); applicationAmendmentRequestResponse.setIsSendNotification(applicationAmendmentRequestEntity.getIsNotification()); String callName = application.getCall().getName(); @@ -642,6 +664,19 @@ public class ApplicationAmendmentRequestDao { log.info("Closing application amendement with ID: {}", id); ApplicationAmendmentRequestEntity existingApplicationAmendment = validateApplicationAmendmentRequest(id); + List amendmentRequestList = applicationAmendmentRequestRepository.findAllByApplicationEvaluationIdAndIsDeletedFalse( + existingApplicationAmendment.getApplicationEvaluationEntity().getId() + ); + + // Check if this is the last amendment being closed + boolean isLastRemaining = amendmentRequestList.stream() + .filter(amendment -> !amendment.getId().equals(id)) // Exclude the current amendment + .allMatch(amendment -> amendment.getStatus().equals(ApplicationAmendmentRequestEnum.CLOSE.getValue())); + + if (isLastRemaining) { + log.info("The current amendment is the last remaining one to be closed."); + applicationAmendmentRequestDao.calculateEndDateAndSuspensionDays(existingApplicationAmendment.getApplicationEvaluationEntity()); + } setIfUpdated(existingApplicationAmendment::getInternalNote, existingApplicationAmendment::setInternalNote, closeAmendmentRequest.getInternalNote()); setIfUpdated(existingApplicationAmendment::getStatus, existingApplicationAmendment::setStatus, ApplicationAmendmentRequestEnum.CLOSE.getValue()); @@ -669,6 +704,7 @@ public class ApplicationAmendmentRequestDao { if (newResponseDays != null && newResponseDays > 0) { Long currentResponseDays = request.getResponseDays() != null ? request.getResponseDays() : 0L; request.setResponseDays(currentResponseDays + newResponseDays); + request.setEndDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now().plusDays(request.getResponseDays()))); applicationAmendmentRequestRepository.save(request); } return convertEntityToResponse(request); @@ -762,12 +798,24 @@ public class ApplicationAmendmentRequestDao { LocalDateTime dueDate = amendment.getStartDate().plusDays(amendment.getResponseDays()); bodyPlaceholders.put("{{amendment_due_date}}", DateTimeUtil.formatLocalDateTime(dueDate, GepafinConstant.DD_MM_YYYY)); } else { - bodyPlaceholders.put("{{amendment_due_date}}", "Not available"); } return Utils.replacePlaceholders(template.getHtmlContent(), bodyPlaceholders); } + public ApplicationEvaluationEntity calculateEndDateAndSuspensionDays(ApplicationEvaluationEntity applicationEvaluationEntity){ + LocalDateTime currentDate=DateTimeUtil.DateServerToUTC(LocalDateTime.now()); + LocalDateTime endDate=currentDate.plusDays(applicationEvaluationEntity.getRemainingDays()); + Long suspendedDays = ChronoUnit.DAYS.between(applicationEvaluationEntity.getStopDateTime(), currentDate); + applicationEvaluationEntity.setEndDate(endDate); + applicationEvaluationEntity.setSuspendedDays(applicationEvaluationEntity.getSuspendedDays()+suspendedDays); + return applicationEvaluationRepository.save(applicationEvaluationEntity); + } + public List getApplicationAmendmentRequestEntitiesByApplicationEvaluationId(Long applicationEvaluationId){ + List applicationAmendmentRequestEntities=new ArrayList<>(); + applicationAmendmentRequestEntities=applicationAmendmentRequestRepository.findAllByApplicationEvaluationIdAndStatusAndIsDeletedFalse(applicationEvaluationId,ApplicationAmendmentRequestEnum.CLOSE.getValue()); + return applicationAmendmentRequestEntities; + } } diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java index 2bcbade9..e9bd2098 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java @@ -17,7 +17,9 @@ import net.gepafin.tendermanagement.repositories.*; import net.gepafin.tendermanagement.service.ApplicationService; import net.gepafin.tendermanagement.service.CallService; import net.gepafin.tendermanagement.service.UserService; +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.springframework.beans.factory.annotation.Autowired; @@ -96,6 +98,11 @@ public class ApplicationEvaluationDao { entity.setFile(Utils.convertObjectToJson(req.getFiles())); entity.setNote(req.getNote()); entity.setIsDeleted(false); + entity.setInitialDays(30L); + entity.setRemainingDays(30L); + entity.setSuspendedDays(0L); + entity.setStartDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); + entity.setEndDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now().plusDays(30))); entity.setStatus(ApplicationEvaluationStatusTypeEnum.OPEN.getValue()); return entity; } @@ -127,6 +134,7 @@ public class ApplicationEvaluationDao { response.setAssignedApplicationId(assignedApplications.getId()); response.setNote(entity.getNote()); response.setStatus(ApplicationEvaluationStatusTypeEnum.valueOf(entity.getStatus())); + response.setEvaluationEndDate(entity.getEndDate()); response.setCreatedDate(entity.getCreatedDate()); response.setUpdatedDate(entity.getUpdatedDate()); } @@ -405,7 +413,6 @@ public class ApplicationEvaluationDao { response.setCallName(application.getCall().getName() != null ? application.getCall().getName() : null); response.setProtocolNumber(application.getProtocol() != null ? application.getProtocol().getProtocolNumber() : null); response.setSubmissionDate(application.getSubmissionDate() != null ? application.getSubmissionDate() : null); - response.setEvaluationDate(application.getSubmissionDate() != null ? application.getSubmissionDate().plusDays(30) : null); LocalDateTime callEndDate = application.getCall().getEndDate(); response.setCallEndDate(callEndDate); } @@ -631,6 +638,7 @@ public class ApplicationEvaluationDao { response.setApplicationStatus(ApplicationStatusTypeEnum.valueOf(application.getStatus())); response.setStatus(ApplicationEvaluationStatusTypeEnum.valueOf(ApplicationEvaluationStatusTypeEnum.OPEN.getValue())); response.setMinScore(call.getThreshold()!=null?call.getThreshold():null); + response.setEvaluationEndDate(entity.getEndDate()); LocalDateTime callEndDate = application.getCall().getEndDate(); response.setCallEndDate(callEndDate); setCriteriaResponses(entity, application.getId(), response, evaluationCriterias); @@ -928,7 +936,6 @@ public class ApplicationEvaluationDao { response.setCallName(application.getCall().getName() != null ? application.getCall().getName() : null); response.setProtocolNumber(application.getProtocol() != null ? application.getProtocol().getProtocolNumber() : null); response.setSubmissionDate(application.getSubmissionDate() != null ? application.getSubmissionDate() : null); - response.setEvaluationDate(application.getSubmissionDate() != null ? application.getSubmissionDate().plusDays(30) : null); } private Optional findFormFieldValue(Long applicationId, String formFieldId) { @@ -1307,10 +1314,10 @@ public class ApplicationEvaluationDao { entity = applicationEvaluationRepository.save(existingEntity); assignedApplicationsRepository.save(assignedApplicationsEntity); - List amendmentRequest = applicationAmendmentRequestRepository.findAllByApplicationEvaluationIdAndIsDeletedFalse(entity.getId()); - for (ApplicationAmendmentRequestEntity request : amendmentRequest) { - request.setStatus(ApplicationAmendmentRequestEnum.CLOSE.getValue()); - } + List amendmentRequest = applicationAmendmentRequestRepository.findAllByApplicationEvaluationIdAndStatusAndIsDeletedFalse(existingEntity.getId(),ApplicationAmendmentRequestEnum.AWAITING.getValue()); + if(amendmentRequest !=null && Boolean.FALSE.equals(amendmentRequest.isEmpty())){ + throw new CustomValidationException(Status.BAD_REQUEST,Translator.toLocale(GepafinConstant.APPLICATION_CANNOT_APPROVED_OR_REJECTED)); + } applicationAmendmentRequestRepository.saveAll(amendmentRequest); if (Boolean.TRUE.equals(statusType.equals((ApplicationStatusTypeEnum.APPROVED.getValue())))) { emailNotificationDao.sendAdmissibilityNotificationEmailForApprovedApplication(application); diff --git a/src/main/java/net/gepafin/tendermanagement/entities/ApplicationAmendmentRequestEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/ApplicationAmendmentRequestEntity.java index 4d2dabf6..4b3fe79c 100644 --- a/src/main/java/net/gepafin/tendermanagement/entities/ApplicationAmendmentRequestEntity.java +++ b/src/main/java/net/gepafin/tendermanagement/entities/ApplicationAmendmentRequestEntity.java @@ -47,4 +47,7 @@ public class ApplicationAmendmentRequestEntity extends BaseEntity { @JoinColumn(name = "PROTOCOL_Id") private ProtocolEntity protocol; + @Column(name = "end_date") + private LocalDateTime endDate; + } diff --git a/src/main/java/net/gepafin/tendermanagement/entities/ApplicationEvaluationEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/ApplicationEvaluationEntity.java index dae9a3fb..8f6eb656 100644 --- a/src/main/java/net/gepafin/tendermanagement/entities/ApplicationEvaluationEntity.java +++ b/src/main/java/net/gepafin/tendermanagement/entities/ApplicationEvaluationEntity.java @@ -3,6 +3,8 @@ package net.gepafin.tendermanagement.entities; import jakarta.persistence.*; import lombok.Data; +import java.time.LocalDateTime; + @Data @Entity @Table(name = "application_evaluation") @@ -35,5 +37,22 @@ public class ApplicationEvaluationEntity extends BaseEntity{ @ManyToOne @JoinColumn(name = "assigned_applications_id", nullable = true) private AssignedApplicationsEntity assignedApplicationsEntity; - + + @Column(name = "INITIAL_DAYS") + private Long initialDays; + + @Column(name = "REMAINING_DAYS") + private Long remainingDays; + + @Column(name = "SUSPENDED_DAYS") + private Long suspendedDays; + + @Column(name = "START_DATE") + private LocalDateTime startDate; + + @Column(name = "END_DATE") + private LocalDateTime endDate; + + @Column(name = "STOP_DATE_TIME") + private LocalDateTime stopDateTime; } diff --git a/src/main/java/net/gepafin/tendermanagement/enums/ApplicationEvaluationStatusTypeEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/ApplicationEvaluationStatusTypeEnum.java index 18cfc30d..59e47f9a 100644 --- a/src/main/java/net/gepafin/tendermanagement/enums/ApplicationEvaluationStatusTypeEnum.java +++ b/src/main/java/net/gepafin/tendermanagement/enums/ApplicationEvaluationStatusTypeEnum.java @@ -5,6 +5,7 @@ import com.fasterxml.jackson.annotation.JsonValue; public enum ApplicationEvaluationStatusTypeEnum { OPEN ("OPEN"), SOCCORSO("SOCCORSO"), + EXPIRED("EXPIRED"), CLOSE("CLOSE"); private String value; diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationAmendmentRequestResponse.java b/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationAmendmentRequestResponse.java index 76e445de..5523098e 100644 --- a/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationAmendmentRequestResponse.java +++ b/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationAmendmentRequestResponse.java @@ -23,6 +23,7 @@ public class ApplicationAmendmentRequestResponse { private List applicationFormFields; private Long applicationId; private Long applicationEvaluationId; + private LocalDateTime evaluationEndDate; private LocalDateTime expirationDate; private List commentsList; private String internalNote; diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationEvaluationResponse.java b/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationEvaluationResponse.java index f0be1236..81d4314d 100644 --- a/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationEvaluationResponse.java +++ b/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationEvaluationResponse.java @@ -27,6 +27,6 @@ public class ApplicationEvaluationResponse { private Long protocolNumber; private String callName; private LocalDateTime submissionDate; - private LocalDateTime evaluationDate; + private LocalDateTime evaluationEndDate; private LocalDateTime callEndDate; } diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationAmendmentRequestRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationAmendmentRequestRepository.java index 57331e43..af46d7b5 100644 --- a/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationAmendmentRequestRepository.java +++ b/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationAmendmentRequestRepository.java @@ -6,6 +6,7 @@ import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; +import java.time.LocalDateTime; import java.util.List; import java.util.Optional; @@ -25,6 +26,7 @@ public interface ApplicationAmendmentRequestRepository extends JpaRepository findAllByApplicationEvaluationIdAndIsDeletedFalse(Long id); @@ -34,4 +36,19 @@ public interface ApplicationAmendmentRequestRepository extends JpaRepository findByApplicationIdAndStatusInAndIsDeletedFalse(Long applicationId, List statuses); + @Query(value = "SELECT amr " + + "FROM ApplicationAmendmentRequestEntity amr " + + "WHERE amr.applicationEvaluationEntity.id = :id " + + "AND amr.isDeleted = false " + + "AND amr.applicationEvaluationEntity.isDeleted = false " + + "AND amr.status = :status") + List findAllByApplicationEvaluationIdAndStatusAndIsDeletedFalse(Long id, String status); + + @Query("SELECT a FROM ApplicationAmendmentRequestEntity a " + + "WHERE a.applicationId = :applicationId " + + "AND a.isDeleted = false " + + "AND a.status <> 'CLOSE' " + + "AND a.endDate < :currentTime") + List findActiveAmendments(Long applicationId, LocalDateTime currentTime); + } diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationEvaluationRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationEvaluationRepository.java index 9ec88ffa..4e4069f3 100644 --- a/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationEvaluationRepository.java +++ b/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationEvaluationRepository.java @@ -6,6 +6,7 @@ import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; +import java.time.LocalDateTime; import java.util.List; import java.util.Optional; @@ -21,5 +22,6 @@ public interface ApplicationEvaluationRepository extends JpaRepository findFirstByIsDeletedFalseOrderByCreatedDateDesc(); boolean existsByApplicationIdAndIsDeletedFalse(Long applicationId); - + @Query("SELECT a FROM ApplicationEvaluationEntity a WHERE a.isDeleted = false AND a.endDate < :currentDate") + List findAllByIsDeletedFalseAndEndDateBefore(@Param("currentDate") LocalDateTime currentDate); } diff --git a/src/main/java/net/gepafin/tendermanagement/scheduler/ApplicationEvaluationScheduler.java b/src/main/java/net/gepafin/tendermanagement/scheduler/ApplicationEvaluationScheduler.java new file mode 100644 index 00000000..9b424e29 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/scheduler/ApplicationEvaluationScheduler.java @@ -0,0 +1,29 @@ +package net.gepafin.tendermanagement.scheduler; + +import net.gepafin.tendermanagement.entities.ApplicationEvaluationEntity; +import net.gepafin.tendermanagement.enums.ApplicationEvaluationStatusTypeEnum; +import net.gepafin.tendermanagement.repositories.ApplicationEvaluationRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.annotation.Scheduled; + +import java.time.LocalDateTime; +import java.util.List; + +public class ApplicationEvaluationScheduler { + + + @Autowired + private ApplicationEvaluationRepository applicationEvaluationRepository; + + @Scheduled(cron = "0 0 1 * * ?") // Runs daily at midnight + public void updateExpiredEvaluations() { + LocalDateTime currentDate = LocalDateTime.now(); + List evaluations = applicationEvaluationRepository.findAllByIsDeletedFalseAndEndDateBefore(currentDate); + + for (ApplicationEvaluationEntity evaluation : evaluations) { + evaluation.setStatus(ApplicationEvaluationStatusTypeEnum.EXPIRED.getValue()); + } + applicationEvaluationRepository.saveAll(evaluations); + } + } + diff --git a/src/main/java/net/gepafin/tendermanagement/scheduler/NotificationScheduler.java b/src/main/java/net/gepafin/tendermanagement/scheduler/NotificationScheduler.java index 58908280..521726a9 100644 --- a/src/main/java/net/gepafin/tendermanagement/scheduler/NotificationScheduler.java +++ b/src/main/java/net/gepafin/tendermanagement/scheduler/NotificationScheduler.java @@ -1,20 +1,26 @@ package net.gepafin.tendermanagement.scheduler; +import net.gepafin.tendermanagement.dao.ApplicationAmendmentRequestDao; import net.gepafin.tendermanagement.dao.EmailNotificationDao; import net.gepafin.tendermanagement.entities.ApplicationAmendmentRequestEntity; import net.gepafin.tendermanagement.entities.ApplicationEntity; +import net.gepafin.tendermanagement.entities.ApplicationEvaluationEntity; import net.gepafin.tendermanagement.entities.UserEntity; import net.gepafin.tendermanagement.enums.ApplicationAmendmentRequestEnum; import net.gepafin.tendermanagement.enums.ApplicationStatusTypeEnum; import net.gepafin.tendermanagement.repositories.ApplicationAmendmentRequestRepository; +import net.gepafin.tendermanagement.repositories.ApplicationEvaluationRepository; import net.gepafin.tendermanagement.repositories.ApplicationRepository; import net.gepafin.tendermanagement.repositories.UserRepository; +import net.gepafin.tendermanagement.util.DateTimeUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import java.time.LocalDateTime; +import java.util.ArrayList; import java.util.List; +import java.util.Optional; @Component public class NotificationScheduler { @@ -31,6 +37,12 @@ public class NotificationScheduler { @Autowired EmailNotificationDao emailNotificationDao; + @Autowired + private ApplicationAmendmentRequestDao applicationAmendmentRequestDao; + + @Autowired + private ApplicationEvaluationRepository applicationEvaluationRepository; + @Scheduled(cron = "0 0 1 * * ?") void sendNotificationForRejectedApplicationToBeneficiary() { @@ -40,17 +52,18 @@ public class NotificationScheduler { LocalDateTime today = LocalDateTime.now(); for (ApplicationEntity application : applicationsList) { - ApplicationAmendmentRequestEntity amendmentRequest = getAmendmentRequestForApplication(application, amendmentRequestList); - - if (amendmentRequest != null) { - LocalDateTime requestDate = amendmentRequest.getStartDate(); - if (requestDate.plusDays(amendmentRequest.getResponseDays()).isBefore(today)) { - // Update the application status to REJECTED + List amendmentRequestEntities = applicationAmendmentRepository.findActiveAmendments(application.getId(), DateTimeUtil.DateServerToUTC(LocalDateTime.now())); + List applicationAmendmentRequestEntities = new ArrayList<>(); + if (amendmentRequestEntities != null && Boolean.FALSE.equals(amendmentRequestEntities.isEmpty())) { + for (ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity : amendmentRequestEntities) { + if (amendmentRequestEntities.size() == 1) { + applicationAmendmentRequestDao.calculateEndDateAndSuspensionDays(applicationAmendmentRequestEntity.getApplicationEvaluationEntity()); + } application.setStatus(ApplicationStatusTypeEnum.REJECTED.getValue()); applicationRepository.save(application); - amendmentRequest.setStatus(ApplicationAmendmentRequestEnum.CLOSE.getValue()); - applicationAmendmentRepository.save(amendmentRequest); - emailNotificationDao.sendApplicationFailureNotificationEmail(amendmentRequest); + applicationAmendmentRequestEntity.setStatus(ApplicationAmendmentRequestEnum.CLOSE.getValue()); + applicationAmendmentRepository.save(applicationAmendmentRequestEntity); + emailNotificationDao.sendApplicationFailureNotificationEmail(applicationAmendmentRequestEntity); } } } 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 a7fe774d..faab8f35 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 @@ -1785,4 +1785,20 @@ + + + + + + + + + + + + + + + + diff --git a/src/main/resources/message_en.properties b/src/main/resources/message_en.properties index 87c95e39..4576117e 100644 --- a/src/main/resources/message_en.properties +++ b/src/main/resources/message_en.properties @@ -309,3 +309,6 @@ DD_MM_YYYY_HH_MM = dd_MM_yyyy HH:mm application.documents.not.found=No documents found for the application. beneficiary.call.duplicate = A preferred call with this call ID and company ID already exists for this user. company.id.required.for.preferred.call=Company ID is required when requesting only preferred calls. + +response.days.not.null=Response days should not be null and greater than zero. +application.cannot.approved.or.rejected=Application cannot be approved and rejected because amendment is active. diff --git a/src/main/resources/message_it.properties b/src/main/resources/message_it.properties index c4763ec7..937a2d21 100644 --- a/src/main/resources/message_it.properties +++ b/src/main/resources/message_it.properties @@ -304,3 +304,5 @@ reminder.email.sent.success.msg=Email di promemoria inviata con successo! application.documents.not.found=Nessun documento trovato per la domanda. beneficiary.call.duplicate = Una chiamata preferita con questo ID di chiamata e ID azienda esiste gi� per questo utente. company.id.required.for.preferred.call=ID azienda obbligatorio quando si richiedono solo chiamate preferite. +response.days.not.null=I giorni di risposta non devono essere nulli e maggiori di zero. +application.cannot.approved.or.rejected=La domanda non può essere approvata o rifiutata perché l'emendamento è attivo. From 6164139450649c00c6c63574a5b791fd79bd7a1d Mon Sep 17 00:00:00 2001 From: rajesh Date: Mon, 25 Nov 2024 00:49:27 +0530 Subject: [PATCH 25/43] Added audit for Application Amendment --- .../dao/ApplicationAmendmentRequestDao.java | 69 ++++++++++++++----- .../enums/UserActionContextEnum.java | 13 ++++ ...ApplicationAmendmentRequestController.java | 60 +++++++++++++++- 3 files changed, 125 insertions(+), 17 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java index d685796f..45e0ab08 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java @@ -11,14 +11,12 @@ import net.gepafin.tendermanagement.constants.GepafinConstant; import net.gepafin.tendermanagement.entities.*; import net.gepafin.tendermanagement.entities.SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum; import net.gepafin.tendermanagement.enums.*; -import net.gepafin.tendermanagement.model.request.ApplicationAmendmentRequest; -import net.gepafin.tendermanagement.model.request.ApplicationAmendmentRequestBean; -import net.gepafin.tendermanagement.model.request.ApplicationFormFieldRequestBean; -import net.gepafin.tendermanagement.model.request.CloseAmendmentRequest; +import net.gepafin.tendermanagement.model.request.*; import net.gepafin.tendermanagement.model.response.*; import net.gepafin.tendermanagement.repositories.*; import net.gepafin.tendermanagement.service.*; import net.gepafin.tendermanagement.util.DateTimeUtil; +import net.gepafin.tendermanagement.util.LoggingUtil; import net.gepafin.tendermanagement.util.Utils; import net.gepafin.tendermanagement.util.Validator; import net.gepafin.tendermanagement.web.rest.api.errors.CustomValidationException; @@ -97,6 +95,12 @@ public class ApplicationAmendmentRequestDao { @Autowired private Validator validator; + @Autowired + LoggingUtil loggingUtil; + + @Autowired + private HttpServletRequest request; + public ApplicationAmendmentRequestResponse getApplicationDataForAmendment(Long applicationEvaluationId) { log.info("Fetching the application data for the Amendment process {}", applicationEvaluationId); ApplicationEvaluationEntity applicationEvaluationEntity = applicationEvaluationService.validateApplicationEvaluation(applicationEvaluationId); @@ -234,25 +238,42 @@ public class ApplicationAmendmentRequestDao { applicationEvaluationEntity.getAssignedApplicationsEntity().getApplication(), protocolNumber, userEntity.getHub().getId()); applicationAmendmentRequestEntity.setProtocol(protocolEntity); - ApplicationAmendmentRequestEntity applicationAmendment = saveApplicationAmendmentRequestEntity(applicationAmendmentRequestEntity); + ApplicationAmendmentRequestEntity applicationAmendment = saveApplicationAmendmentRequestEntity(applicationAmendmentRequestEntity,null,VersionActionTypeEnum.INSERT); //Set Status + ApplicationEvaluationEntity oldApplicationEvaluationEntity = Utils.getClonedEntityForData(applicationEvaluationEntity); applicationEvaluationEntity.setStatus(ApplicationEvaluationStatusTypeEnum.SOCCORSO.getValue()); applicationEvaluationRepository.save(applicationEvaluationEntity); + /** This code is responsible for adding a version history log for the "Update Application Evaluation" operation. **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplicationEvaluationEntity).newData(applicationEvaluationEntity).build()); + + ApplicationEntity applicationEntity = applicationService.validateApplication(applicationId); + ApplicationEntity oldApplicationEntity = Utils.getClonedEntityForData(applicationEntity); applicationEntity.setStatus(ApplicationStatusTypeEnum.SOCCORSO.getValue()); applicationRepository.save(applicationEntity); + /** This code is responsible for adding a version history log for the "Update Application" operation. **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplicationEntity).newData(applicationEntity).build()); + AssignedApplicationsEntity assignedApplicationsEntity = assignedApplicationsService.validateAssignedApplication(assignedApplicationId); + AssignedApplicationsEntity oldAssignedApplication = Utils.getClonedEntityForData(assignedApplicationsEntity); assignedApplicationsEntity.setStatus(AssignedApplicationEnum.SOCCORSO.getValue()); assignedApplicationsRepository.save(assignedApplicationsEntity); + /** This code is responsible for adding a version history log for the "Update Assigned Application" operation. **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldAssignedApplication).newData(assignedApplicationsEntity).build()); + return applicationAmendment; } - public ApplicationAmendmentRequestEntity saveApplicationAmendmentRequestEntity(ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity) { + public ApplicationAmendmentRequestEntity saveApplicationAmendmentRequestEntity(ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity,ApplicationAmendmentRequestEntity oldApplicationAmendmentEntity,VersionActionTypeEnum actionTypeEnum) { ApplicationAmendmentRequestEntity applicationAmendmentRequest = applicationAmendmentRequestRepository.save(applicationAmendmentRequestEntity); + + /** This code is responsible for adding a version history log for the "Create Application Amendment" operation. **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(actionTypeEnum).oldData(oldApplicationAmendmentEntity).newData(applicationAmendmentRequestEntity).build()); + return applicationAmendmentRequest; } @@ -391,8 +412,9 @@ public class ApplicationAmendmentRequestDao { public void deleteById(Long id) { log.info("Deleting assigned application with ID: {}", id); ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity = validateApplicationAmendmentRequest(id); + ApplicationAmendmentRequestEntity oldApplicationAmendmentEntity = Utils.getClonedEntityForData(applicationAmendmentRequestEntity); applicationAmendmentRequestEntity.setIsDeleted(true); - saveApplicationAmendmentRequestEntity(applicationAmendmentRequestEntity); + saveApplicationAmendmentRequestEntity(applicationAmendmentRequestEntity,oldApplicationAmendmentEntity,VersionActionTypeEnum.SOFT_DELETE); log.info(" Application amendment deleted with ID: {}", id); } @@ -440,6 +462,7 @@ public class ApplicationAmendmentRequestDao { log.info("Updating application amendement with ID: {}", id); ApplicationAmendmentRequestEntity existingApplicationAmendment = validateApplicationAmendmentRequest(id); + ApplicationAmendmentRequestEntity oldApplicationAmendmentEntity = Utils.getClonedEntityForData(existingApplicationAmendment); setIfUpdated(existingApplicationAmendment::getNote, existingApplicationAmendment::setNote, updateRequest.getNote()); if (updateRequest.getApplicationFormFields() != null) { updateApplicationFormFields(existingApplicationAmendment, updateRequest.getApplicationFormFields()); @@ -447,7 +470,7 @@ public class ApplicationAmendmentRequestDao { } existingApplicationAmendment.setUpdatedDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); - ApplicationAmendmentRequestEntity updatedApplicationAmendment = saveApplicationAmendmentRequestEntity(existingApplicationAmendment); + ApplicationAmendmentRequestEntity updatedApplicationAmendment = saveApplicationAmendmentRequestEntity(existingApplicationAmendment,oldApplicationAmendmentEntity,VersionActionTypeEnum.UPDATE); ApplicationAmendmentRequestResponse response = convertEntityToResponse(updatedApplicationAmendment); log.info("Application Amendment updated successfully: {}", response); return response; @@ -641,11 +664,11 @@ public class ApplicationAmendmentRequestDao { public ApplicationAmendmentRequestResponse closeAmendmentRequest(Long id, CloseAmendmentRequest closeAmendmentRequest) { log.info("Closing application amendement with ID: {}", id); ApplicationAmendmentRequestEntity existingApplicationAmendment = validateApplicationAmendmentRequest(id); - + ApplicationAmendmentRequestEntity oldApplicationAmendmentEntity = Utils.getClonedEntityForData(existingApplicationAmendment); setIfUpdated(existingApplicationAmendment::getInternalNote, existingApplicationAmendment::setInternalNote, closeAmendmentRequest.getInternalNote()); setIfUpdated(existingApplicationAmendment::getStatus, existingApplicationAmendment::setStatus, ApplicationAmendmentRequestEnum.CLOSE.getValue()); - ApplicationAmendmentRequestEntity updatedApplicationAmendment = saveApplicationAmendmentRequestEntity(existingApplicationAmendment); + ApplicationAmendmentRequestEntity updatedApplicationAmendment = saveApplicationAmendmentRequestEntity(existingApplicationAmendment,oldApplicationAmendmentEntity,VersionActionTypeEnum.UPDATE); ApplicationAmendmentRequestResponse response = convertEntityToResponse(updatedApplicationAmendment); List amendmentRequests = applicationAmendmentRequestRepository.findAllByApplicationEvaluationIdAndIsDeletedFalse(existingApplicationAmendment.getApplicationEvaluationEntity().getId()); @@ -653,8 +676,13 @@ public class ApplicationAmendmentRequestDao { .allMatch(amendment -> amendment.getStatus().equals(ApplicationAmendmentRequestEnum.CLOSE.getValue())); if (allClosed) { - existingApplicationAmendment.getApplicationEvaluationEntity().setStatus(ApplicationEvaluationStatusTypeEnum.OPEN.getValue()); + ApplicationEvaluationEntity existingApplicationEvaluationEntity = existingApplicationAmendment.getApplicationEvaluationEntity(); + ApplicationEvaluationEntity oldApplicationEvaluationEntity = Utils.getClonedEntityForData(existingApplicationEvaluationEntity); + existingApplicationEvaluationEntity.setStatus(ApplicationEvaluationStatusTypeEnum.OPEN.getValue()); applicationEvaluationRepository.save(existingApplicationAmendment.getApplicationEvaluationEntity()); + + /** This code is responsible for adding a version history log for the "Update Application Evaluation" operation. **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplicationEvaluationEntity).newData(existingApplicationEvaluationEntity).build()); log.info("All amendments are closed. Application Evaluation status set to OPEN."); } log.info("Application Amendment closed successfully: {}", response); @@ -662,16 +690,21 @@ public class ApplicationAmendmentRequestDao { } public ApplicationAmendmentRequestResponse extendResponseDays(Long id, Long newResponseDays) { - ApplicationAmendmentRequestEntity request = applicationAmendmentRequestRepository.findByIdAndIsDeletedFalse(id) + ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity = applicationAmendmentRequestRepository.findByIdAndIsDeletedFalse(id) .orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.APPLICATION_AMENDMENT_NOT_FOUND_MSG))); if (newResponseDays != null && newResponseDays > 0) { - Long currentResponseDays = request.getResponseDays() != null ? request.getResponseDays() : 0L; - request.setResponseDays(currentResponseDays + newResponseDays); - applicationAmendmentRequestRepository.save(request); + ApplicationAmendmentRequestEntity oldApplicationAmendmentEntity = Utils.getClonedEntityForData(applicationAmendmentRequestEntity); + Long currentResponseDays = applicationAmendmentRequestEntity.getResponseDays() != null ? applicationAmendmentRequestEntity.getResponseDays() : 0L; + applicationAmendmentRequestEntity.setResponseDays(currentResponseDays + newResponseDays); + applicationAmendmentRequestRepository.save(applicationAmendmentRequestEntity); + + /** This code is responsible for adding a version history log for the "Update Application Amendment" operation. **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplicationAmendmentEntity).newData(applicationAmendmentRequestEntity).build()); + } - return convertEntityToResponse(request); + return convertEntityToResponse(applicationAmendmentRequestEntity); } public List getAmendmentByApplicationId(HttpServletRequest request, Long applicationId, List statuses) { @@ -707,10 +740,14 @@ public class ApplicationAmendmentRequestDao { log.info("Updating application amendement with status: {}", id); ApplicationAmendmentRequestEntity existingApplicationAmendment = validateApplicationAmendmentRequest(id); + ApplicationAmendmentRequestEntity oldApplicationAmendmentEntity = Utils.getClonedEntityForData(existingApplicationAmendment); if (Boolean.TRUE.equals(existingApplicationAmendment.getStatus().equals(ApplicationAmendmentRequestEnum.AWAITING.getValue())) && Boolean.TRUE.equals(statusTypeEnum.equals(ApplicationAmendmentRequestEnum.RESPONSE_RECEIVED))) { existingApplicationAmendment.setStatus(ApplicationAmendmentRequestEnum.RESPONSE_RECEIVED.getValue()); existingApplicationAmendment.setUpdatedDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); applicationAmendmentRequestRepository.save(existingApplicationAmendment); + + /** This code is responsible for adding a version history log for the "Update Application Amendment" operation. **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplicationAmendmentEntity).newData(existingApplicationAmendment).build()); } ApplicationAmendmentRequestResponse response = convertEntityToResponse(existingApplicationAmendment); log.info("Amendment status updated successfully: {}", response); diff --git a/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java index c269e62f..bb336e68 100644 --- a/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java +++ b/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java @@ -60,6 +60,19 @@ public enum UserActionContextEnum { GET_ALL_HUB("GET_ALL_HUB"), GET_HUB_BY_UUID(" GET_HUB_BY_UUID"), + /** amendment action context **/ + CREATE_AMENDMENT("CREATE_AMENDMENT"), + GET_AMENDMENT(" GET_AMENDMENT"), + CLOSE_AMENDMENT("CLOSE_AMENDMENT"), + UPDATE_AMENDMENT("UPDATE_AMENDMENT"), + DELETE_AMENDMENT("DELETE_AMENDMENT"), + UPDATE_AMENDMENT_STATUS("UPDATE_AMENDMENT_STATUS"), + GET_ALL_AMENDMENT_BY_PREINSTRUCTOR_USER_ID("GET_AMENDMENT_BY_PREINSTRUCTOR_USER_ID"), + GET_ALL_AMENDMENT_BY_BENEFICIARY_USER_ID("GET_AMENDMENT_BY_BENEFICIARY_USER_ID"), + GET_AMENDMENT_BY_APPLICATION_ID("GET_AMENDMENT_BY_APPLICATION_ID"), + EXTEND_RESPONSE_DAYS_FOR_AMENDMENT("EXTEND_RESPONSE_DAYS_FOR_AMENDMENT"), + GET_APPLICATION_DATA_FOR_AMENDMENT("GET_APPLICATION_DATA_FOR_AMENDMENT"), + /** Application Evaluation action context **/ CREATE_UPDATE_APPLICATION_EVALUATION("CREATE_UPDATE_APPLICATION_EVALUATION"), GET_APPLICATION_EVALUATION("GET_APPLICATION_EVALUATION"), diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/ApplicationAmendmentRequestController.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/ApplicationAmendmentRequestController.java index bd66efd1..d4707511 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/ApplicationAmendmentRequestController.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/ApplicationAmendmentRequestController.java @@ -5,13 +5,16 @@ import lombok.extern.log4j.Log4j2; import net.gepafin.tendermanagement.config.Translator; import net.gepafin.tendermanagement.constants.GepafinConstant; import net.gepafin.tendermanagement.enums.ApplicationAmendmentRequestEnum; -import net.gepafin.tendermanagement.enums.ApplicationStatusTypeEnum; +import net.gepafin.tendermanagement.enums.UserActionContextEnum; +import net.gepafin.tendermanagement.enums.UserActionLogsEnum; import net.gepafin.tendermanagement.model.request.ApplicationAmendmentRequest; import net.gepafin.tendermanagement.model.request.ApplicationAmendmentRequestBean; import net.gepafin.tendermanagement.model.request.CloseAmendmentRequest; +import net.gepafin.tendermanagement.model.request.UserActionRequest; import net.gepafin.tendermanagement.model.response.ApplicationAmendmentRequestResponse; import net.gepafin.tendermanagement.model.util.Response; import net.gepafin.tendermanagement.service.ApplicationAmendmentRequestService; +import net.gepafin.tendermanagement.util.LoggingUtil; import net.gepafin.tendermanagement.web.rest.api.ApplicationAmendmentRequestApi; import net.gepafin.tendermanagement.web.rest.api.errors.Status; import org.springframework.beans.factory.annotation.Autowired; @@ -29,8 +32,16 @@ public class ApplicationAmendmentRequestController implements ApplicationAmendme @Autowired ApplicationAmendmentRequestService applicationAmendmentRequestService; + @Autowired + LoggingUtil loggingUtil; + @Override public ResponseEntity> getApplicationDataForAmendment(HttpServletRequest request, Long applicationEvaluationId) { + + /** This code is responsible for creating user action logs for the "get application data for amendment" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.VIEW) + .actionContext(UserActionContextEnum.GET_APPLICATION_DATA_FOR_AMENDMENT).build()); + ApplicationAmendmentRequestResponse applicationAmendmentBean = applicationAmendmentRequestService.getApplicationDataForAmendment(request,applicationEvaluationId); return ResponseEntity.status(HttpStatus.OK) .body(new Response<>(applicationAmendmentBean, Status.SUCCESS, Translator.toLocale(GepafinConstant.APPLICATION_DATA_FOR_AMENDMENT_SUCCESS_MSG))); @@ -38,6 +49,11 @@ public class ApplicationAmendmentRequestController implements ApplicationAmendme @Override public ResponseEntity> createApplicationAmendmentRequest(HttpServletRequest request, Long applicationEvaluationId, ApplicationAmendmentRequest applicationAmendmentRequest) { + + /** This code is responsible for creating user action logs for the "Create Application Amendment" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.INSERT) + .actionContext(UserActionContextEnum.CREATE_AMENDMENT).build()); + ApplicationAmendmentRequestResponse applicationAmendmentRequestResponse = applicationAmendmentRequestService.createApplicationAmendmentRequest(request,applicationEvaluationId,applicationAmendmentRequest); return ResponseEntity.status(HttpStatus.OK) .body(new Response<>(applicationAmendmentRequestResponse, Status.SUCCESS, Translator.toLocale(GepafinConstant.CREATE_APPLICATION_DATA_FOR_AMENDMENT_MSG))); @@ -46,6 +62,10 @@ public class ApplicationAmendmentRequestController implements ApplicationAmendme @Override public ResponseEntity> deleteApplicationAmendmentRequest(HttpServletRequest request, Long id) { log.info("Delete Application Amendment Request- Application Amendment ID: {}", id); + + /** This code is responsible for creating user action logs for the "Delete Amendment" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.DELETE).actionContext(UserActionContextEnum.DELETE_AMENDMENT).build()); + applicationAmendmentRequestService.deleteApplicationAmendmentRequest(request,id); return ResponseEntity.status(HttpStatus.OK) .body(new Response<>(null, Status.SUCCESS, Translator.toLocale(GepafinConstant.DELETE_APPLICATION_AMENDMENT_SUCCESS_MSG))); @@ -54,6 +74,11 @@ public class ApplicationAmendmentRequestController implements ApplicationAmendme @Override public ResponseEntity> getApplicationAmendmentRequestById(HttpServletRequest request,Long id) { log.info("Get Application Amendment Request By Id"); + + /** This code is responsible for creating user action logs for the "get application amendment by id" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.VIEW) + .actionContext(UserActionContextEnum.GET_AMENDMENT).build()); + ApplicationAmendmentRequestResponse applicationAmendmentRequestResponse = applicationAmendmentRequestService.getApplicationAmendmentRequestById(request,id); return ResponseEntity.status(HttpStatus.OK) .body(new Response<>(applicationAmendmentRequestResponse, Status.SUCCESS, Translator.toLocale(GepafinConstant.GET_APPLICATION_AMENDMENT_SUCCESS_MSG))); @@ -62,6 +87,11 @@ public class ApplicationAmendmentRequestController implements ApplicationAmendme @Override public ResponseEntity>> getAllApplicationAmendmentRequest(HttpServletRequest request,Long userId) { log.info("Get All Applications Amendment Request"); + + /** This code is responsible for creating user action logs for the "get all application amendment by preInstructor user id" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.VIEW) + .actionContext(UserActionContextEnum.GET_ALL_AMENDMENT_BY_PREINSTRUCTOR_USER_ID).build()); + List applicationAmendmentRequestResponses = applicationAmendmentRequestService.getAllApplicationAmendmentRequest(request,userId); return ResponseEntity.status(HttpStatus.OK) .body(new Response<>(applicationAmendmentRequestResponses, Status.SUCCESS, Translator.toLocale(GepafinConstant.GET_APPLICATION_AMENDMENT_SUCCESS_MSG))); @@ -70,6 +100,11 @@ public class ApplicationAmendmentRequestController implements ApplicationAmendme @Override public ResponseEntity> updateApplicationAmendment(HttpServletRequest request, Long id, ApplicationAmendmentRequestBean applicationAmendmentRequestBean) { log.info("Update Application Amendment"); + + /** This code is responsible for "Updating Amendment" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.UPDATE) + .actionContext(UserActionContextEnum.UPDATE_AMENDMENT).build()); + ApplicationAmendmentRequestResponse updateApplicationAmendment = applicationAmendmentRequestService.updateApplicationAmendment(request, id, applicationAmendmentRequestBean); return ResponseEntity.status(HttpStatus.CREATED) .body(new Response<>(updateApplicationAmendment, Status.SUCCESS, Translator.toLocale(GepafinConstant.APPLICATION_AMENDMENT_UPDATE_SUCCESSFULLY_MSG))); @@ -78,6 +113,11 @@ public class ApplicationAmendmentRequestController implements ApplicationAmendme @Override public ResponseEntity>> getAllAmendmentRequestByBeneficiaryId(HttpServletRequest request, Long beneficiaryId) { log.info("Get All Application Amendment Request By Beneficiary ID"); + + /** This code is responsible for creating user action logs for the "get all application amendment by beneficiary user id" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.VIEW) + .actionContext(UserActionContextEnum.GET_ALL_AMENDMENT_BY_BENEFICIARY_USER_ID).build()); + List applicationAmendmentRequestResponseList = applicationAmendmentRequestService.getAllAmendmentRequestByBeneficiaryId(request, beneficiaryId); return ResponseEntity.status(HttpStatus.CREATED) .body(new Response<>(applicationAmendmentRequestResponseList, Status.SUCCESS, Translator.toLocale(GepafinConstant.GET_APPLICATION_AMENDMENT_SUCCESS_MSG))); @@ -86,6 +126,11 @@ public class ApplicationAmendmentRequestController implements ApplicationAmendme @Override public ResponseEntity> closeApplicationAmendmentRequest(HttpServletRequest request, Long id, CloseAmendmentRequest closeAmendmentRequest) { log.info("Closing Amendment Request"); + + /** This code is responsible for "Close Amendment" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.UPDATE) + .actionContext(UserActionContextEnum.CLOSE_AMENDMENT).build()); + ApplicationAmendmentRequestResponse amendmentRequestResponse = applicationAmendmentRequestService.closeAmendmentRequest(request, id,closeAmendmentRequest); return ResponseEntity.status(HttpStatus.CREATED) .body(new Response<>(amendmentRequestResponse, Status.SUCCESS, Translator.toLocale(GepafinConstant.APPLICATION_AMENDMENT_CLOSED_SUCCESFULLY))); @@ -99,6 +144,10 @@ public class ApplicationAmendmentRequestController implements ApplicationAmendme log.info("Extending response days for Amendment Request ID: {}", id); + /** This code is responsible for "Extend Response Days for Amendment" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.UPDATE) + .actionContext(UserActionContextEnum.EXTEND_RESPONSE_DAYS_FOR_AMENDMENT).build()); + ApplicationAmendmentRequestResponse response = applicationAmendmentRequestService.extendResponseDays(request, id, addedDays); return ResponseEntity.status(HttpStatus.OK) @@ -106,6 +155,11 @@ public class ApplicationAmendmentRequestController implements ApplicationAmendme } @Override public ResponseEntity>> getAmendmentByApplicationId(HttpServletRequest request, Long applicationId,List statuses) { + + /** This code is responsible for creating user action logs for the "get all application amendment by application id" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.VIEW) + .actionContext(UserActionContextEnum.GET_AMENDMENT_BY_APPLICATION_ID).build()); + List applicationAmendmentBean = applicationAmendmentRequestService.getAmendmentByApplicationId(request,applicationId,statuses); return ResponseEntity.status(HttpStatus.OK) .body(new Response<>(applicationAmendmentBean, Status.SUCCESS, Translator.toLocale(GepafinConstant.APPLICATION_DATA_FOR_AMENDMENT_SUCCESS_MSG))); @@ -113,6 +167,10 @@ public class ApplicationAmendmentRequestController implements ApplicationAmendme @Override public ResponseEntity> updateApplicationAmendmentStatus(HttpServletRequest request, Long applicationAmendmentId, ApplicationAmendmentRequestEnum status) { + /** This code is responsible for "Updating Amendment Status" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.UPDATE) + .actionContext(UserActionContextEnum.UPDATE_AMENDMENT_STATUS).build()); + ApplicationAmendmentRequestResponse applicationResponse = applicationAmendmentRequestService.updateApplicationAmendmentStatus(request, applicationAmendmentId, status); return ResponseEntity.status(HttpStatus.OK) .body(new Response<>(applicationResponse, Status.SUCCESS, Translator.toLocale(GepafinConstant.APPLICATION_AMENDMENT_UPDATE_SUCCESSFULLY_MSG))); From ba71b77f179382f5f1afb4ec84e48955b01b4ba7 Mon Sep 17 00:00:00 2001 From: piyushkag Date: Mon, 25 Nov 2024 11:14:12 +0530 Subject: [PATCH 26/43] Added user action and versoining for evaluation criteria. --- .../dao/EvaluationCriteriaDao.java | 168 +++++++++++------- .../enums/UserActionContextEnum.java | 8 +- .../impl/EvaluationCriteriaApiController.java | 23 +++ 3 files changed, 135 insertions(+), 64 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/EvaluationCriteriaDao.java b/src/main/java/net/gepafin/tendermanagement/dao/EvaluationCriteriaDao.java index 86a7693f..8f7897c4 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/EvaluationCriteriaDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/EvaluationCriteriaDao.java @@ -1,17 +1,22 @@ 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.CallEntity; import net.gepafin.tendermanagement.entities.CriteriaFormFieldEntity; import net.gepafin.tendermanagement.entities.EvaluationCriteriaEntity; import net.gepafin.tendermanagement.entities.LookUpDataEntity; +import net.gepafin.tendermanagement.enums.VersionActionTypeEnum; import net.gepafin.tendermanagement.model.request.EvaluationCriteriaRequest; +import net.gepafin.tendermanagement.model.request.VersionHistoryRequest; import net.gepafin.tendermanagement.model.response.EvaluationCriteriaResponseBean; import net.gepafin.tendermanagement.repositories.CriteriaFormFieldRepository; import net.gepafin.tendermanagement.repositories.EvaluationCriteriaRepository; import net.gepafin.tendermanagement.service.CallService; import net.gepafin.tendermanagement.service.LookUpDataService; +import net.gepafin.tendermanagement.util.LoggingUtil; +import net.gepafin.tendermanagement.util.Utils; import net.gepafin.tendermanagement.web.rest.api.errors.ResourceNotFoundException; import net.gepafin.tendermanagement.web.rest.api.errors.Status; @@ -35,72 +40,109 @@ public class EvaluationCriteriaDao { @Autowired private CriteriaFormFieldRepository criteriaFormFieldRepository; - public EvaluationCriteriaResponseBean createEvaluationCriteria( - EvaluationCriteriaRequest evaluationCriteriaRequest) { - EvaluationCriteriaEntity entity = convertEvaluationCriteriaRequestToEvaluationCriteriaEntity( - evaluationCriteriaRequest); - return convertEvaluationCriteriaEntityEvaluationCriteriaToResponseBean(entity); - } + @Autowired + private LoggingUtil loggingUtil; - private EvaluationCriteriaEntity convertEvaluationCriteriaRequestToEvaluationCriteriaEntity( - EvaluationCriteriaRequest evaluationCriteriaRequest) { - EvaluationCriteriaEntity entity = new EvaluationCriteriaEntity(); - CallEntity callEntity = callService.validateCall(evaluationCriteriaRequest.getCallId()); - LookUpDataEntity looDataEntity = lookUpDataService - .validateLookUpData(evaluationCriteriaRequest.getLookUpDataId()); - entity.setCall(callEntity); - entity.setLookupData(looDataEntity); - entity.setScore(0L); - if (evaluationCriteriaRequest.getScore() != null) { - entity.setScore(evaluationCriteriaRequest.getScore()); - } - entity = evaluationCriteriaRepository.save(entity); - return entity; - } + @Autowired + private HttpServletRequest request; - public EvaluationCriteriaResponseBean getEvaluationCriteriaById(Long id) { - return evaluationCriteriaRepository.findById(id) - .map(this::convertEvaluationCriteriaEntityEvaluationCriteriaToResponseBean) - .orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND, - Translator.toLocale(GepafinConstant.EVALUATION_CRITERIA_NOT_FOUND))); - } - - public EvaluationCriteriaEntity validateEvaluationCriteria(Long id) { - return evaluationCriteriaRepository.findById(id) - .orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND, - Translator.toLocale(GepafinConstant.EVALUATION_CRITERIA_NOT_FOUND))); - } + public EvaluationCriteriaResponseBean createEvaluationCriteria(EvaluationCriteriaRequest evaluationCriteriaRequest) { - public EvaluationCriteriaResponseBean updateEvaluationCriteria(Long id, EvaluationCriteriaRequest request) { - EvaluationCriteriaEntity entity = evaluationCriteriaRepository.findById(id) - .orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND, - Translator.toLocale(GepafinConstant.EVALUATION_CRITERIA_NOT_FOUND))); - entity = convertEvaluationCriteriaRequestToEvaluationCriteriaEntity(request); - return convertEvaluationCriteriaEntityEvaluationCriteriaToResponseBean(entity); - } + EvaluationCriteriaEntity entity = convertEvaluationCriteriaRequestToEvaluationCriteriaEntity(evaluationCriteriaRequest, VersionActionTypeEnum.INSERT, null); + return convertEvaluationCriteriaEntityEvaluationCriteriaToResponseBean(entity); + } - public void deleteEvaluationCriteria(Long id) { - evaluationCriteriaRepository.deleteById(id); - EvaluationCriteriaEntity evaluationCriteriaEntity = validateEvaluationCriteria(id); - evaluationCriteriaEntity.setIsDeleted(Boolean.TRUE); - evaluationCriteriaRepository.save(evaluationCriteriaEntity); - List list = criteriaFormFieldRepository.findByEvaluationCriteriaIdAndIsDeletedFalse(evaluationCriteriaEntity.getId()) - .stream() - .peek(data -> data.setIsDeleted(Boolean.TRUE)) - .toList();; - criteriaFormFieldRepository.saveAll(list); - } + private EvaluationCriteriaEntity convertEvaluationCriteriaRequestToEvaluationCriteriaEntity(EvaluationCriteriaRequest evaluationCriteriaRequest, + VersionActionTypeEnum actionType, EvaluationCriteriaEntity evaluationCriteriaEntity) { - private EvaluationCriteriaResponseBean convertEvaluationCriteriaEntityEvaluationCriteriaToResponseBean( - EvaluationCriteriaEntity entity) { - EvaluationCriteriaResponseBean response = new EvaluationCriteriaResponseBean(); - response.setId(entity.getId()); - response.setScore(entity.getScore()); - response.setCreatedDate(entity.getCreatedDate()); - response.setUpdatedDate(entity.getUpdatedDate()); - response.setLookUpDataId(entity.getLookupData().getId()); - response.setTitle(entity.getLookupData().getTitle()); - response.setValue(entity.getLookupData().getValue()); - return response; - } + EvaluationCriteriaEntity entity; + if (evaluationCriteriaEntity != null && evaluationCriteriaEntity.getId() != null) { + entity = evaluationCriteriaEntity; + } else { + entity = new EvaluationCriteriaEntity(); + } + //cloned for old data + EvaluationCriteriaEntity oldEvaluationCriteriaData = Utils.getClonedEntityForData(entity); + + CallEntity callEntity = callService.validateCall(evaluationCriteriaRequest.getCallId()); + LookUpDataEntity lookupDataEntity = lookUpDataService.getOrCreateLookUpDataEntity(evaluationCriteriaRequest, LookUpDataEntity.LookUpDataTypeEnum.EVALUATION_CRITERIA); + entity.setCall(callEntity); + entity.setLookupData(lookupDataEntity); + entity.setScore(0L); + if (evaluationCriteriaRequest.getScore() != null) { + entity.setScore(evaluationCriteriaRequest.getScore()); + } + entity = evaluationCriteriaRepository.save(entity); + + /** This code is responsible for adding a version history log for the "updating or creating evaluation criteria" operation. **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(actionType).oldData(oldEvaluationCriteriaData).newData(entity).build()); + + return entity; + } + + public EvaluationCriteriaResponseBean getEvaluationCriteriaById(Long id) { + + return evaluationCriteriaRepository.findById(id).map(this::convertEvaluationCriteriaEntityEvaluationCriteriaToResponseBean) + .orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.EVALUATION_CRITERIA_NOT_FOUND))); + } + + public EvaluationCriteriaEntity validateEvaluationCriteria(Long id) { + + return evaluationCriteriaRepository.findById(id) + .orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.EVALUATION_CRITERIA_NOT_FOUND))); + } + + public EvaluationCriteriaResponseBean updateEvaluationCriteria(Long id, EvaluationCriteriaRequest evaluationCriteriaRequest) { + + EvaluationCriteriaEntity entity = evaluationCriteriaRepository.findById(id) + .orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.EVALUATION_CRITERIA_NOT_FOUND))); + + entity = convertEvaluationCriteriaRequestToEvaluationCriteriaEntity(evaluationCriteriaRequest, VersionActionTypeEnum.UPDATE, entity); + return convertEvaluationCriteriaEntityEvaluationCriteriaToResponseBean(entity); + } + + public void deleteEvaluationCriteria(Long id) { + // evaluationCriteriaRepository.deleteById(id); // Not needed if setting isDeleted TRUE in the next line after fetching evaluation criteria + EvaluationCriteriaEntity evaluationCriteriaEntity = validateEvaluationCriteria(id); + + // Clone the evaluation criteria entity for old data + EvaluationCriteriaEntity oldEvaluationCriteriaData = Utils.getClonedEntityForData(evaluationCriteriaEntity); + + List oldList = criteriaFormFieldRepository.findByEvaluationCriteriaIdAndIsDeletedFalse(evaluationCriteriaEntity.getId()).stream() + .map(Utils::getClonedEntityForData).toList(); + + evaluationCriteriaEntity.setIsDeleted(Boolean.TRUE); + evaluationCriteriaEntity = evaluationCriteriaRepository.save(evaluationCriteriaEntity); + + /** This code is responsible for adding a version history log for the "updating evaluation criteria" operation. **/ + loggingUtil.addVersionHistory( + VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.SOFT_DELETE).oldData(oldEvaluationCriteriaData).newData(evaluationCriteriaEntity) + .build()); + + List updatedList = criteriaFormFieldRepository.findByEvaluationCriteriaIdAndIsDeletedFalse(evaluationCriteriaEntity.getId()).stream() + .peek(data -> data.setIsDeleted(Boolean.TRUE)).toList(); + + List softDeletingSavedList = criteriaFormFieldRepository.saveAll(updatedList); + + softDeletingSavedList.forEach(data -> { + CriteriaFormFieldEntity oldFieldData = oldList.stream().filter(old -> old.getId().equals(data.getId())).findFirst().orElse(null); + + /** This code is responsible for adding a version history log for the "Soft deleting criteria form field" operation. **/ + loggingUtil.addVersionHistory( + VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.SOFT_DELETE).oldData(oldFieldData).newData(data).build()); + }); + } + + private EvaluationCriteriaResponseBean convertEvaluationCriteriaEntityEvaluationCriteriaToResponseBean(EvaluationCriteriaEntity entity) { + + EvaluationCriteriaResponseBean response = new EvaluationCriteriaResponseBean(); + response.setId(entity.getId()); + response.setScore(entity.getScore()); + response.setCreatedDate(entity.getCreatedDate()); + response.setUpdatedDate(entity.getUpdatedDate()); + response.setLookUpDataId(entity.getLookupData().getId()); + response.setTitle(entity.getLookupData().getTitle()); + response.setValue(entity.getLookupData().getValue()); + return response; + } } diff --git a/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java index cd567918..0864ac4d 100644 --- a/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java +++ b/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java @@ -116,7 +116,13 @@ public enum UserActionContextEnum { /** Dashboard action context **/ GET_DASHBOARD_WIDGET_FOR_SUPER_ADMIN("GET_DASHBOARD_WIDGET_FOR_SUPER_ADMIN"), - GET_DASHBOARD_WIDGET_FOR_BENEFICIARY("GET_DASHBOARD_WIDGET_FOR_BENEFICIARY"); + GET_DASHBOARD_WIDGET_FOR_BENEFICIARY("GET_DASHBOARD_WIDGET_FOR_BENEFICIARY"), + + /** Evaluation criteria action context **/ + GET_EVALUATION_CRITERIA("GET_EVALUATION_CRITERIA"), + UPDATE_EVALUATION_CRITERIA("UPDATE_EVALUATION_CRITERIA"), + DELETE_EVALUATION_CRITERIA("DELETE_EVALUATION_CRITERIA"), + CREATE_EVALUATION_CRITERIA("CREATE_EVALUATION_CRITERIA"); private final String value; diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/EvaluationCriteriaApiController.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/EvaluationCriteriaApiController.java index 37e8b7a6..cc64b15c 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/EvaluationCriteriaApiController.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/EvaluationCriteriaApiController.java @@ -2,10 +2,14 @@ package net.gepafin.tendermanagement.web.rest.api.impl; 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.EvaluationCriteriaRequest; +import net.gepafin.tendermanagement.model.request.UserActionRequest; import net.gepafin.tendermanagement.model.response.EvaluationCriteriaResponseBean; import net.gepafin.tendermanagement.model.util.Response; import net.gepafin.tendermanagement.service.EvaluationCriteriaService; +import net.gepafin.tendermanagement.util.LoggingUtil; import net.gepafin.tendermanagement.web.rest.api.EvaluationCriteriaApi; import net.gepafin.tendermanagement.web.rest.api.errors.Status; import org.springframework.beans.factory.annotation.Autowired; @@ -24,8 +28,15 @@ public class EvaluationCriteriaApiController implements EvaluationCriteriaApi { @Autowired private EvaluationCriteriaService service; + @Autowired + private LoggingUtil loggingUtil; + @Override public ResponseEntity> createEvaluationCriteria(HttpServletRequest request, EvaluationCriteriaRequest evaluationCriteriaRequest) { + + /** This code is responsible for creating user action logs for the "create evaluation criteria" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.INSERT).actionContext(UserActionContextEnum.CREATE_EVALUATION_CRITERIA).build()); + EvaluationCriteriaResponseBean responseBean = service.createEvaluationCriteria(request,evaluationCriteriaRequest); return ResponseEntity.status(HttpStatus.CREATED) .body(new Response<>(responseBean, Status.SUCCESS, Translator.toLocale(GepafinConstant.EVALUATION_CRITERIA_CREATED_SUCCESSFULLY))); @@ -33,6 +44,10 @@ public class EvaluationCriteriaApiController implements EvaluationCriteriaApi { @Override public ResponseEntity> getEvaluationCriteriaById(HttpServletRequest request, Long id) { + + /** This code is responsible for creating user action logs for the "get evaluation criteria" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.VIEW).actionContext(UserActionContextEnum.GET_EVALUATION_CRITERIA).build()); + EvaluationCriteriaResponseBean responseBean = service.getEvaluationCriteria(request,id); if (responseBean != null) { return ResponseEntity.status(HttpStatus.OK) @@ -46,6 +61,10 @@ public class EvaluationCriteriaApiController implements EvaluationCriteriaApi { @Override @Transactional(rollbackFor=Exception.class) public ResponseEntity> updateEvaluationCriteria(HttpServletRequest request, Long id, EvaluationCriteriaRequest evaluationCriteriaRequest) { + + /** This code is responsible for creating user action logs for the "Update evaluation criteria" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.UPDATE).actionContext(UserActionContextEnum.UPDATE_EVALUATION_CRITERIA).build()); + EvaluationCriteriaResponseBean responseBean = service.updateEvaluationCriteria(request,id, evaluationCriteriaRequest); if (responseBean != null) { return ResponseEntity.status(HttpStatus.OK) @@ -58,6 +77,10 @@ public class EvaluationCriteriaApiController implements EvaluationCriteriaApi { @Override public ResponseEntity> deleteEvaluationCriteria(HttpServletRequest request, Long id) { + + /** This code is responsible for creating user action logs for the "deleting evaluation criteria" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.DELETE).actionContext(UserActionContextEnum.DELETE_EVALUATION_CRITERIA).build()); + service.deleteEvaluationCriteria(request,id); return ResponseEntity.status(HttpStatus.OK) From fa5faffa58c83a1a67f547ca7f8783f1fd121ae2 Mon Sep 17 00:00:00 2001 From: rajesh Date: Mon, 25 Nov 2024 12:57:00 +0530 Subject: [PATCH 27/43] Added user action and versioning for create flow data --- .../gepafin/tendermanagement/dao/FlowDao.java | 96 ++++++++++++++++--- 1 file changed, 83 insertions(+), 13 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/FlowDao.java b/src/main/java/net/gepafin/tendermanagement/dao/FlowDao.java index b4db5ff5..c298cbd4 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/FlowDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/FlowDao.java @@ -6,9 +6,11 @@ import net.gepafin.tendermanagement.entities.CallEntity; import net.gepafin.tendermanagement.entities.FlowDataEntity; import net.gepafin.tendermanagement.entities.FlowEdgesEntity; import net.gepafin.tendermanagement.enums.CallStatusEnum; +import net.gepafin.tendermanagement.enums.VersionActionTypeEnum; import net.gepafin.tendermanagement.model.request.FlowDataRequestBean; import net.gepafin.tendermanagement.model.request.FlowEdgesRequestBean; import net.gepafin.tendermanagement.model.request.FlowRequestBean; +import net.gepafin.tendermanagement.model.request.VersionHistoryRequest; import net.gepafin.tendermanagement.model.response.FlowDataResponseBean; import net.gepafin.tendermanagement.model.response.FlowEdgesResponseBean; import net.gepafin.tendermanagement.model.response.FlowResponseBean; @@ -19,11 +21,17 @@ import net.gepafin.tendermanagement.service.CallService; import net.gepafin.tendermanagement.service.FormService; 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.web.rest.api.errors.CustomValidationException; import net.gepafin.tendermanagement.web.rest.api.errors.Status; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import com.itextpdf.text.pdf.PdfStructTreeController.returnType; + +import jakarta.servlet.http.HttpServletRequest; + import java.time.LocalDateTime; import java.util.List; import java.util.stream.Collectors; @@ -47,7 +55,10 @@ public class FlowDao { private FormService formService; @Autowired - private CallDao callDao; + private LoggingUtil loggingUtil; + + @Autowired + private HttpServletRequest request; public FlowResponseBean createOrUpdateFlow(FlowRequestBean flowRequestBean, Long callId) { validateFlowRequestBean(flowRequestBean); @@ -76,11 +87,43 @@ public class FlowDao { List flowDataEntities = flowDataRepository.findByCallId(call.getId()); List flowEdgesEntities = flowEdgesRepository.findByCallId(call.getId()); if (Boolean.FALSE.equals(flowDataEntities.isEmpty()) || Boolean.FALSE.equals(flowEdgesEntities.isEmpty())) { - call.setInitialForm(null); - call.setFinalForm(null); - call=callRepository.save(call); + if (call.getInitialForm() != null || call.getInitialForm() != null) { + CallEntity oldCallEntity = Utils.getClonedEntityForData(call); + call.setInitialForm(null); + call.setFinalForm(null); + call = callRepository.save(call); + + /** + * This code is responsible for adding a version history log for the "update + * call for flow" operation. + **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request) + .actionType(VersionActionTypeEnum.UPDATE).oldData(oldCallEntity).newData(call).build()); + + } flowDataRepository.deleteAll(flowDataEntities); flowEdgesRepository.deleteAll(flowEdgesEntities); + + flowDataEntities.forEach(data->{ + /** + * This code is responsible for adding a version history log for the "update + * call for flow" operation. + **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request) + .actionType(VersionActionTypeEnum.DELETE).oldData(data).newData(null).build()); + }); + + flowEdgesEntities.forEach(data->{ + /** + * This code is responsible for adding a version history log for the "update + * call for flow" operation. + **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request) + .actionType(VersionActionTypeEnum.DELETE).oldData(data).newData(null).build()); + + }); + + } } @@ -110,20 +153,38 @@ public class FlowDao { return flowResponseBean; } - private CallEntity setInitialAndFinalFormInCall(FlowRequestBean flowRequestBean, CallEntity call) { - call.setInitialForm(flowRequestBean.getInitialForm()); - call.setFinalForm(flowRequestBean.getFinalForm()); - call.setUpdatedDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); - call = callRepository.save(call); - return call; - } + private CallEntity setInitialAndFinalFormInCall(FlowRequestBean flowRequestBean, CallEntity call) { + + CallEntity oldCallEntity = Utils.getClonedEntityForData(call); + call.setInitialForm(flowRequestBean.getInitialForm()); + call.setFinalForm(flowRequestBean.getFinalForm()); + call.setUpdatedDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); + call = callRepository.save(call); + + /** + * This code is responsible for adding a version history log for the "update + * call for flow" operation. + **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request) + .actionType(VersionActionTypeEnum.UPDATE).oldData(oldCallEntity).newData(call).build()); + return call; + } public List createFlowData(FlowRequestBean flowRequestBean, CallEntity call) { if (flowRequestBean.getFlowData() != null || !flowRequestBean.getFlowEdges().isEmpty()) { List flowDataEntities = flowRequestBean.getFlowData().stream() .map(flowDataRequestBean -> createFlowDataEntity(flowDataRequestBean, call)) .collect(Collectors.toList()); - return flowDataRepository.saveAll(flowDataEntities); + flowDataEntities = flowDataRepository.saveAll(flowDataEntities); + flowDataEntities.forEach(data->{ + + /** + * This code is responsible for adding a version history log for the "delete flow data" operation. + **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request) + .actionType(VersionActionTypeEnum.INSERT).oldData(null).newData(data).build()); + }); + return flowDataEntities; } return null; } @@ -145,7 +206,16 @@ public class FlowDao { List flowEdgesEntities = flowRequestBean.getFlowEdges().stream() .map(flowEdgesRequestBean -> createFlowEdgesEntity(flowEdgesRequestBean, call)) .collect(Collectors.toList()); - return flowEdgesRepository.saveAll(flowEdgesEntities); + flowEdgesEntities = flowEdgesRepository.saveAll(flowEdgesEntities); + flowEdgesEntities.forEach(data->{ + /** + * This code is responsible for adding a version history log for the "update + * call for flow" operation. + **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request) + .actionType(VersionActionTypeEnum.INSERT).oldData(null).newData(data).build()); + }); + return flowEdgesEntities; } public FlowEdgesEntity createFlowEdgesEntity(FlowEdgesRequestBean flowEdgesRequestBean,CallEntity call) { From c1313f1591d79eb8a82fbffcf2c58a152685acac Mon Sep 17 00:00:00 2001 From: nisha Date: Tue, 26 Nov 2024 09:46:18 +0530 Subject: [PATCH 28/43] Updated code --- .../dao/AssignedApplicationsDao.java | 13 +++++++++++-- .../response/AssignedApplicationsResponse.java | 1 + 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/AssignedApplicationsDao.java b/src/main/java/net/gepafin/tendermanagement/dao/AssignedApplicationsDao.java index 1617b3e7..68cc26a7 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/AssignedApplicationsDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/AssignedApplicationsDao.java @@ -4,6 +4,7 @@ import jakarta.servlet.http.HttpServletRequest; import net.gepafin.tendermanagement.config.Translator; import net.gepafin.tendermanagement.constants.GepafinConstant; import net.gepafin.tendermanagement.entities.ApplicationEntity; +import net.gepafin.tendermanagement.entities.ApplicationEvaluationEntity; import net.gepafin.tendermanagement.entities.AssignedApplicationsEntity; import net.gepafin.tendermanagement.entities.UserEntity; import net.gepafin.tendermanagement.enums.ApplicationStatusTypeEnum; @@ -11,6 +12,7 @@ import net.gepafin.tendermanagement.enums.AssignedApplicationEnum; import net.gepafin.tendermanagement.model.request.ApplicationEvaluationRequest; import net.gepafin.tendermanagement.model.request.AssignedApplicationsRequest; import net.gepafin.tendermanagement.model.response.AssignedApplicationsResponse; +import net.gepafin.tendermanagement.repositories.ApplicationEvaluationRepository; import net.gepafin.tendermanagement.repositories.ApplicationRepository; import net.gepafin.tendermanagement.repositories.AssignedApplicationsRepository; import net.gepafin.tendermanagement.service.ApplicationService; @@ -26,6 +28,7 @@ import org.springframework.stereotype.Component; import java.time.LocalDateTime; import java.util.List; +import java.util.Optional; import java.util.stream.Collectors; import static net.gepafin.tendermanagement.util.Utils.log; @@ -51,6 +54,9 @@ public class AssignedApplicationsDao { @Autowired private ApplicationEvaluationDao applicationEvaluationDao; + @Autowired + private ApplicationEvaluationRepository applicationEvaluationRepository; + public AssignedApplicationsResponse createAssignedApplications(Long applicationId, Long userId, UserEntity assignedByUser, AssignedApplicationsRequest assignedApplicationsRequest){ log.info("Assigning application to pre-Instructor with details: {}", applicationId,userId); @@ -71,8 +77,8 @@ public class AssignedApplicationsDao { applicationRepository.save(application); UserEntity user = userService.validateUser(userId); AssignedApplicationsEntity assignment = createAssignmentEntity(application, user.getId(), assignedByUser, assignedApplicationsRequest); + applicationEvaluationDao.createOrUpdateApplicationEvaluation(user, new ApplicationEvaluationRequest(), assignment.getId()); AssignedApplicationsResponse assignApplicationToInstructorResponse = convertEntityToResponse(assignment); - applicationEvaluationDao.createOrUpdateApplicationEvaluation(user, new ApplicationEvaluationRequest(), assignApplicationToInstructorResponse.getId()); log.info("Application assigned succesfully {}", assignApplicationToInstructorResponse); return assignApplicationToInstructorResponse; } @@ -105,6 +111,7 @@ public class AssignedApplicationsDao { ApplicationEntity application = applicationService.validateApplication(assignedApplications.getApplication().getId()); String callName = application.getCall() != null ? application.getCall().getName() : ""; + Optional applicationEvaluationEntity=applicationEvaluationRepository.findByApplicationIdAndIsDeletedFalse(application.getId()); LocalDateTime callEndDate = application.getCall().getEndDate(); LocalDateTime callStartDate = application.getCall().getStartDate(); @@ -136,7 +143,9 @@ public class AssignedApplicationsDao { assignedApplicationsResponse.setSubmissionDate(submissionDate); assignedApplicationsResponse.setCallEndDate(callEndDate); assignedApplicationsResponse.setCallStartDate(callStartDate); - + if(applicationEvaluationEntity.isPresent()){ + assignedApplicationsResponse.setEvaluationEndDate(applicationEvaluationEntity.get().getEndDate()); + } return assignedApplicationsResponse; } diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/AssignedApplicationsResponse.java b/src/main/java/net/gepafin/tendermanagement/model/response/AssignedApplicationsResponse.java index 3affe42f..b975c150 100644 --- a/src/main/java/net/gepafin/tendermanagement/model/response/AssignedApplicationsResponse.java +++ b/src/main/java/net/gepafin/tendermanagement/model/response/AssignedApplicationsResponse.java @@ -21,6 +21,7 @@ public class AssignedApplicationsResponse extends BaseBean { private LocalDateTime callStartDate; private LocalDateTime callEndDate; private String companyName; + private LocalDateTime evaluationEndDate; } From 7d04e4ab5837ce9022bedd07924ff09c1fae384d Mon Sep 17 00:00:00 2001 From: piyushkag Date: Tue, 26 Nov 2024 12:47:03 +0530 Subject: [PATCH 29/43] Added user action log and versioning for communication. --- .../dao/CommunicationDao.java | 34 +++++++++++++++++-- .../enums/UserActionContextEnum.java | 8 ++++- .../response/CommunicationResponseBean.java | 9 +++-- .../repositories/CommunicationRepository.java | 10 +++--- .../impl/CommunicationServiceImpl.java | 2 +- .../tendermanagement/util/LoggingUtil.java | 31 +++++++++++++++-- .../api/impl/CommunicationController.java | 19 +++++++++++ 7 files changed, 99 insertions(+), 14 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/CommunicationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/CommunicationDao.java index b752a755..d7ef7c83 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/CommunicationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/CommunicationDao.java @@ -5,14 +5,19 @@ import net.gepafin.tendermanagement.config.Translator; import net.gepafin.tendermanagement.constants.GepafinConstant; import net.gepafin.tendermanagement.entities.ApplicationAmendmentRequestEntity; import net.gepafin.tendermanagement.entities.CommunicationEntity; +import net.gepafin.tendermanagement.enums.VersionActionTypeEnum; import net.gepafin.tendermanagement.model.request.CommunicationRequestBean; +import net.gepafin.tendermanagement.model.request.VersionHistoryRequest; import net.gepafin.tendermanagement.model.response.ApplicationAmendmentResponse; import net.gepafin.tendermanagement.model.response.CommunicationResponseBean; import net.gepafin.tendermanagement.repositories.CommunicationRepository; import net.gepafin.tendermanagement.service.ApplicationAmendmentRequestService; +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; import net.gepafin.tendermanagement.web.rest.api.errors.Status; +import org.checkerframework.checker.units.qual.A; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -34,24 +39,41 @@ public class CommunicationDao { @Autowired private Validator validator; + @Autowired + private LoggingUtil loggingUtil; + + @Autowired + private HttpServletRequest request; + public CommunicationResponseBean addCommentToAmendmentRequest(HttpServletRequest request, CommunicationRequestBean communicationReq, Long amendmentId) { log.info("Adding communication request..."); CommunicationEntity communicationEntity = convertToCommunicationCommentEntity(communicationReq, amendmentId); communicationEntity = communicationRepository.save(communicationEntity); + + /** This code is responsible for adding a version history log for the "adding comment to amendment request" operation. **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.INSERT).oldData(null).newData(communicationEntity).build()); + log.info("Added comment: {}", communicationEntity); return convertToCommunicationResponseBean(communicationEntity); } public String deleteComment(Long amendmentId, Long commentId) { - CommunicationEntity data = communicationRepository.findById(commentId) + CommunicationEntity data = communicationRepository.findByIdAndIsDeletedFalse(commentId) .orElseThrow(() -> new CustomValidationException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.COMMENT_NOT_FOUND))); + //cloned for old commentData + CommunicationEntity oldComment = Utils.getClonedEntityForData(data); + if (!data.getApplicationAmendmentRequest().getId().equals(amendmentId)) { throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.INVALID_AMENDMENT_FOR_COMMENT)); } data.setIsDeleted(true); - communicationRepository.save(data); + data = communicationRepository.save(data); + + /** This code is responsible for adding a version history log for the "soft deleting comment to amendment request" operation. **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.SOFT_DELETE).oldData(oldComment).newData(data).build()); + return "Deleted Comment Successfully."; } @@ -70,6 +92,9 @@ public class CommunicationDao { log.info("Updating communication comment..."); CommunicationEntity existingComment = communicationRepository.findById(commentId) .orElseThrow(() -> new CustomValidationException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.COMMENT_NOT_FOUND))); + //cloned for old data for communication + CommunicationEntity oldCommentData = Utils.getClonedEntityForData(existingComment); + if (!existingComment.getApplicationAmendmentRequest().getId().equals(amendmentId)) { throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.COMMENT_NOT_ASSOCIATE_WITH_AMENDMENT_ID_ERROR_MSG)); } @@ -78,6 +103,10 @@ public class CommunicationDao { existingComment.setCommentedDate(LocalDateTime.now()); existingComment = communicationRepository.save(existingComment); log.info("Updated Comment: {}", existingComment); + + /** This code is responsible for adding a version history log for the "updating comment to amendment request" operation. **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldCommentData).newData(existingComment).build()); + return convertToCommunicationResponseBean(existingComment); } @@ -92,6 +121,7 @@ public class CommunicationDao { response.setTitle(entity.getCommunicationTitle()); response.setSenderUserId(entity.getSenderUserId()); response.setReceiverUserId(entity.getReceiverUserId()); + response.setId(entity.getId()); return response; } diff --git a/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java index d19d9d33..fefc12a9 100644 --- a/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java +++ b/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java @@ -135,7 +135,13 @@ public enum UserActionContextEnum { GET_EVALUATION_CRITERIA("GET_EVALUATION_CRITERIA"), UPDATE_EVALUATION_CRITERIA("UPDATE_EVALUATION_CRITERIA"), DELETE_EVALUATION_CRITERIA("DELETE_EVALUATION_CRITERIA"), - CREATE_EVALUATION_CRITERIA("CREATE_EVALUATION_CRITERIA"); + CREATE_EVALUATION_CRITERIA("CREATE_EVALUATION_CRITERIA"), + + /** communication action context **/ + 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"); private final String value; diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/CommunicationResponseBean.java b/src/main/java/net/gepafin/tendermanagement/model/response/CommunicationResponseBean.java index 4593db84..170e1318 100644 --- a/src/main/java/net/gepafin/tendermanagement/model/response/CommunicationResponseBean.java +++ b/src/main/java/net/gepafin/tendermanagement/model/response/CommunicationResponseBean.java @@ -10,6 +10,8 @@ public class CommunicationResponseBean { private String comment; + private Long id; + private String title; private LocalDateTime createdDate; @@ -21,7 +23,8 @@ public class CommunicationResponseBean { private Long receiverUserId; private Long amendmentId; - public CommunicationResponseBean(LocalDateTime commentedDate, String comment, String title, LocalDateTime createdDate, LocalDateTime updatedDate, Long amendmentId) { + + public CommunicationResponseBean(LocalDateTime commentedDate, String comment, String title, LocalDateTime createdDate, LocalDateTime updatedDate, Long amendmentId, Long id) { this.commentedDate = commentedDate; this.comment = comment; @@ -29,9 +32,10 @@ public class CommunicationResponseBean { this.createdDate = createdDate; this.updatedDate = updatedDate; this.amendmentId = amendmentId; + this.id = id; } - public CommunicationResponseBean(LocalDateTime commentedDate, String comment, String title, LocalDateTime createdDate, LocalDateTime updatedDate, Long amendmentId,Long senderUserId,Long receiverUserId) { + public CommunicationResponseBean(LocalDateTime commentedDate, String comment, String title, LocalDateTime createdDate, LocalDateTime updatedDate, Long amendmentId,Long senderUserId,Long receiverUserId, Long id) { this.commentedDate = commentedDate; this.comment = comment; @@ -41,6 +45,7 @@ public class CommunicationResponseBean { this.amendmentId = amendmentId; this.senderUserId = senderUserId; this.receiverUserId = receiverUserId; + this.id = id; } public CommunicationResponseBean() { diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/CommunicationRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/CommunicationRepository.java index f92b9a06..2894d57b 100644 --- a/src/main/java/net/gepafin/tendermanagement/repositories/CommunicationRepository.java +++ b/src/main/java/net/gepafin/tendermanagement/repositories/CommunicationRepository.java @@ -7,16 +7,14 @@ import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; import java.util.List; +import java.util.Optional; public interface CommunicationRepository extends JpaRepository { - @Query("Select new net.gepafin.tendermanagement.model.response.CommunicationResponseBean(c.commentedDate, c.communicationComment, c.communicationTitle, c.createdDate, c.updatedDate, c.applicationAmendmentRequest.id) " + - "from CommunicationEntity c Where c.applicationAmendmentRequest.id = :applicationAmendmentRequestId") - List findCommentsByApplicationAmendmentRequestId(@Param("applicationAmendmentRequestId") Long amendmentRequestId); - @Query("SELECT new net.gepafin.tendermanagement.model.response.CommunicationResponseBean( " + "c.commentedDate, c.communicationComment, c.communicationTitle, c.createdDate, c" + - ".updatedDate, c.applicationAmendmentRequest.id,c.senderUserId, c.receiverUserId) " + "FROM CommunicationEntity c " + "WHERE c.applicationAmendmentRequest.id = :amendmentId AND c.isDeleted = false") + ".updatedDate, " + "c.applicationAmendmentRequest.id, c.senderUserId, c.receiverUserId, c.id " + ") " + "FROM CommunicationEntity c " + "WHERE c" + + ".applicationAmendmentRequest.id = :amendmentId AND c.isDeleted = false") List findCommentListDetailsByAmendmentId(@Param("amendmentId") Long amendmentId); - + Optional findByIdAndIsDeletedFalse(Long commentId); } diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/CommunicationServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/CommunicationServiceImpl.java index de3e5030..ad3513e3 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/CommunicationServiceImpl.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/CommunicationServiceImpl.java @@ -63,7 +63,7 @@ public class CommunicationServiceImpl implements CommunicationService { } @Override - @Transactional(readOnly = true) + @Transactional(rollbackFor = Exception.class) public ApplicationAmendmentResponse getAmendmentComments(HttpServletRequest request,Long id) { ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity = applicationAmendmentRequestDao.validateApplicationAmendmentRequest(id); if (Boolean.FALSE.equals(validator.checkIsBeneficiary())) { diff --git a/src/main/java/net/gepafin/tendermanagement/util/LoggingUtil.java b/src/main/java/net/gepafin/tendermanagement/util/LoggingUtil.java index d3a60884..53ed01cb 100644 --- a/src/main/java/net/gepafin/tendermanagement/util/LoggingUtil.java +++ b/src/main/java/net/gepafin/tendermanagement/util/LoggingUtil.java @@ -19,6 +19,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.web.context.annotation.RequestScope; +import java.net.URLDecoder; +import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.List; import java.util.Map; @@ -55,12 +57,26 @@ public class LoggingUtil { if (userActionRequest.getRequest() instanceof CachedBodyHttpServletRequest cachedRequest) { requestBody = cachedRequest.getCachedBodyAsString(); } + // Decode the raw URI to handle encoded placeholders like %7BcommentId%7D + String rawUrl = userActionRequest.getRequest().getRequestURI(); + String decodedUrl = URLDecoder.decode(rawUrl, StandardCharsets.UTF_8); + + // Append query parameters if they exist + if (userActionRequest.getRequest().getQueryString() != null) { + decodedUrl += "?" + userActionRequest.getRequest().getQueryString(); + } + + // Use the decoded URL as-is (optional normalization step if needed) + String normalizedUrl = normalizeUrl(decodedUrl); + + // Set the normalized URL in the user action log userAction.setActionType(userActionRequest.getActionType().getValue()); userAction.setUserId(userId); userAction.setActionContext(userActionRequest.getActionContext().getValue()); userAction.setMethodType(userActionRequest.getRequest().getMethod()); userAction.setHubId(userEntity.getHub().getId()); - userAction.setUrl(userActionRequest.getRequest().getRequestURI()); +// userAction.setUrl(userActionRequest.getRequest().getRequestURI()); + userAction.setUrl(normalizedUrl); userAction.setLoginAttemptId(loginAttemptId); userAction.setIpAddress(IpAddressUtils.getClientIp(userActionRequest.getRequest())); userAction.setRequestBody(requestBody); @@ -74,7 +90,18 @@ public class LoggingUtil { return userAction; } -// @Transactional + private String normalizeUrl(String url) { + + url = url.replaceAll("(? 1 && url.endsWith("/")) { + url = url.substring(0, url.length() - 1); + } + url = URLDecoder.decode(url, StandardCharsets.UTF_8); + return url; + } + + + // @Transactional // public UserActionEntity updateUserAction(HttpServletResponse response, UserActionEntity userAction) { // try { // String requestBody = null; diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/CommunicationController.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/CommunicationController.java index 92aa71cf..15552e95 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/CommunicationController.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/CommunicationController.java @@ -3,11 +3,15 @@ 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.CommunicationRequestBean; +import net.gepafin.tendermanagement.model.request.UserActionRequest; import net.gepafin.tendermanagement.model.response.ApplicationAmendmentResponse; import net.gepafin.tendermanagement.model.response.CommunicationResponseBean; import net.gepafin.tendermanagement.model.util.Response; import net.gepafin.tendermanagement.service.CommunicationService; +import net.gepafin.tendermanagement.util.LoggingUtil; import net.gepafin.tendermanagement.web.rest.api.CommunicationApi; import net.gepafin.tendermanagement.web.rest.api.errors.Status; import org.springframework.beans.factory.annotation.Autowired; @@ -23,10 +27,16 @@ public class CommunicationController implements CommunicationApi { @Autowired CommunicationService communicationService; + @Autowired + private LoggingUtil loggingUtil; + @Override public ResponseEntity> addCommentToAmendmentRequest(HttpServletRequest request, CommunicationRequestBean communicationRequestBean, Long amendmentId) { + /** This code is responsible for creating user action logs for the "Adding comment to amendment request" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.INSERT).actionContext(UserActionContextEnum.ADD_COMMENT_TO_AMENDMENT_REQUEST).build()); + CommunicationResponseBean communicationResponseBean = communicationService.addCommentToAmendmentRequest(request,communicationRequestBean, amendmentId); return ResponseEntity.status(HttpStatus.CREATED) .body(new Response<>(communicationResponseBean, Status.SUCCESS, Translator.toLocale(GepafinConstant.COMMUNICATION_ADDED_TO_AMENDMENT_REQUEST_SUCCESS))); @@ -34,6 +44,9 @@ public class CommunicationController implements CommunicationApi { @Override public ResponseEntity> getAmendmentComments(HttpServletRequest request,Long amendmentId) { + /** This code is responsible for creating user action logs for the "getting comment of amendment" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.VIEW).actionContext(UserActionContextEnum.GET_AMENDMENT_COMMENT).build()); + ApplicationAmendmentResponse response = communicationService.getAmendmentComments(request,amendmentId); return ResponseEntity.ok(new Response<>(response, Status.SUCCESS, Translator.toLocale(GepafinConstant.AMENDMENT_FOUND_SUCCESS))); } @@ -41,6 +54,9 @@ public class CommunicationController implements CommunicationApi { public ResponseEntity> updateCommunicationAmendment(HttpServletRequest request, CommunicationRequestBean communicationRequestBean, Long amendmentId, Long commentId) { + /** This code is responsible for creating user action logs for the "update communication comment of amendment request" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.UPDATE).actionContext(UserActionContextEnum.UPDATE_COMMUNICATION_COMMENT).build()); + CommunicationResponseBean communicationResponseBean = communicationService.updateAmendmentComment(request,communicationRequestBean, amendmentId, commentId); return ResponseEntity.status(HttpStatus.OK) .body(new Response<>(communicationResponseBean, Status.SUCCESS, Translator.toLocale(GepafinConstant.COMMENT_UPDATED_SUCCESS_MSG))); @@ -48,6 +64,9 @@ public class CommunicationController implements CommunicationApi { @Override public ResponseEntity> deleteApplicationAmendmentComment(HttpServletRequest request, Long applicationAmendId, Long commentId) { + /** This code is responsible for creating user action logs for the "Delete communication comment of amendment request" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.DELETE).actionContext(UserActionContextEnum.DELETE_COMMENT_FROM_AMENDMENT).build()); + String communicationResponseBean = communicationService.deleteComment(request,applicationAmendId, commentId); return ResponseEntity.status(HttpStatus.OK) .body(new Response<>(communicationResponseBean, Status.SUCCESS, Translator.toLocale(GepafinConstant.COMMENT_DELETED_SUCCESS_MSG))); From f6a5dd45231b1732f5277c545ca09ee472d457e3 Mon Sep 17 00:00:00 2001 From: piyushkag Date: Tue, 26 Nov 2024 15:44:21 +0530 Subject: [PATCH 30/43] Added user action and versioning in form. --- .../gepafin/tendermanagement/dao/FormDao.java | 213 +++++++++++++----- .../enums/UserActionContextEnum.java | 8 +- .../web/rest/api/impl/FormApiController.java | 27 +++ 3 files changed, 191 insertions(+), 57 deletions(-) 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))); From 202e9604a8d26e1af618539694b6168539760d4f Mon Sep 17 00:00:00 2001 From: rajesh Date: Tue, 26 Nov 2024 17:07:25 +0530 Subject: [PATCH 31/43] Deleted Documents --- .../tendermanagement/dao/DelegationDao.java | 1 + .../tendermanagement/dao/DocumentDao.java | 44 +++++--- .../enums/DocOtherSourceTypeEnum.java | 5 +- .../service/AmazonS3Service.java | 18 +++- .../service/impl/AmazonS3ServiceImpl.java | 101 ++++++++++++++++++ 5 files changed, 152 insertions(+), 17 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/DelegationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/DelegationDao.java index dfc65ec7..3fd9d83f 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/DelegationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/DelegationDao.java @@ -255,6 +255,7 @@ public class DelegationDao { throw new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.DELEGATION_NOT_FOUND)); } + amazonS3Service.deleteDelegationfromS3(userCompanyDelegationEntity); userCompanyDelegationEntity.setStatus(UserCompanyDelegationStatusEnum.INACTIVE.getValue()); userCompanyDelegationRepository.save(userCompanyDelegationEntity); } diff --git a/src/main/java/net/gepafin/tendermanagement/dao/DocumentDao.java b/src/main/java/net/gepafin/tendermanagement/dao/DocumentDao.java index 6f8e3243..1ccd9386 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/DocumentDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/DocumentDao.java @@ -1,30 +1,29 @@ package net.gepafin.tendermanagement.dao; - -import java.util.stream.Collectors; - import lombok.extern.slf4j.Slf4j; -import net.gepafin.tendermanagement.enums.DocumentSourceTypeEnum; -import net.gepafin.tendermanagement.repositories.ApplicationRepository; -import net.gepafin.tendermanagement.web.rest.api.errors.CustomValidationException; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; -import org.springframework.web.multipart.MultipartFile; - import net.gepafin.tendermanagement.config.Translator; import net.gepafin.tendermanagement.constants.GepafinConstant; +import net.gepafin.tendermanagement.entities.ApplicationEntity; import net.gepafin.tendermanagement.entities.CallEntity; import net.gepafin.tendermanagement.entities.DocumentEntity; +import net.gepafin.tendermanagement.enums.DocumentSourceTypeEnum; import net.gepafin.tendermanagement.enums.DocumentTypeEnum; import net.gepafin.tendermanagement.model.response.DocumentResponseBean; import net.gepafin.tendermanagement.model.response.UploadFileOnAmazonS3Response; +import net.gepafin.tendermanagement.repositories.ApplicationRepository; import net.gepafin.tendermanagement.repositories.DocumentRepository; import net.gepafin.tendermanagement.service.AmazonS3Service; +import net.gepafin.tendermanagement.service.ApplicationService; import net.gepafin.tendermanagement.service.CallService; +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.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; +import org.springframework.web.multipart.MultipartFile; import java.util.ArrayList; import java.util.List; +import java.util.stream.Collectors; @Slf4j @Component @@ -47,6 +46,14 @@ public class DocumentDao { @Autowired private ApplicationRepository applicationFormRepository; + + @Autowired + ApplicationService applicationService; + + @Value("${aws.s3.bucket.name}") + private String bucketName; + + // @Value("${aws.s3.url.folder}") // private String s3Folder; @@ -110,13 +117,22 @@ public class DocumentDao { public void deleteFile(Long documentId) { DocumentEntity documentEntity = validateDocument(documentId); -// String fileName= Utils.extractFileName(documentEntity.getFilePath()); -// deleteFileOnAmazonS3(fileName); + Long callId = null; + Long applicationId = null; + + if ("CALL".equalsIgnoreCase(documentEntity.getSource())) { + callId = documentEntity.getSourceId(); + } else if ("APPLICATION".equalsIgnoreCase(documentEntity.getSource())) { + applicationId = documentEntity.getSourceId(); + ApplicationEntity applicationEntity = applicationService.validateApplication(applicationId); + callId = applicationEntity.getCall().getId(); + } + + amazonS3Service.deleteFileFromS3(documentEntity,callId,applicationId); documentEntity.setIsDeleted(true); documentRepository.save(documentEntity); } - public DocumentEntity validateDocument(Long id) { return documentRepository.findById(id).orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.DOCUMENT_NOT_FOUND))); diff --git a/src/main/java/net/gepafin/tendermanagement/enums/DocOtherSourceTypeEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/DocOtherSourceTypeEnum.java index 751dfa92..998c7d13 100644 --- a/src/main/java/net/gepafin/tendermanagement/enums/DocOtherSourceTypeEnum.java +++ b/src/main/java/net/gepafin/tendermanagement/enums/DocOtherSourceTypeEnum.java @@ -3,7 +3,10 @@ package net.gepafin.tendermanagement.enums; public enum DocOtherSourceTypeEnum { USER_SIGNED_DOCUMENT("USER_SIGNED_DOCUMENT"), USER_DELEGATION("USER_DELEGATION"), - TEMPLATE("TEMPLATE"); + TEMPLATE("TEMPLATE"), + DELETED_USER_DELEGATION("DELETED_USER_DELEGATION"), + DELETED_APPLICATION("DELETED_APPLICATION"), + DELETED_CALL("DELETED_CALL"); private String value; diff --git a/src/main/java/net/gepafin/tendermanagement/service/AmazonS3Service.java b/src/main/java/net/gepafin/tendermanagement/service/AmazonS3Service.java index 6cc27000..92cbdfab 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/AmazonS3Service.java +++ b/src/main/java/net/gepafin/tendermanagement/service/AmazonS3Service.java @@ -1,5 +1,8 @@ package net.gepafin.tendermanagement.service; +import net.gepafin.tendermanagement.entities.DocumentEntity; +import net.gepafin.tendermanagement.entities.UserCompanyDelegationEntity; +import net.gepafin.tendermanagement.enums.DocOtherSourceTypeEnum; import org.springframework.stereotype.Component; import org.springframework.web.multipart.MultipartFile; @@ -9,12 +12,23 @@ import java.io.IOException; import java.io.InputStream; @Component -public interface AmazonS3Service { +public interface +AmazonS3Service { UploadFileOnAmazonS3Response uploadFileOnAmazonS3(String s3Folder, MultipartFile file); Boolean delete(String s3Folder, String filePath); InputStream getFile(String s3Folder, String filePath) throws IOException; - + + String generateS3PathForDeletedDocument(DocOtherSourceTypeEnum typeOfDocument, Long callId, Long applicationId); + + String generateS3PathForDeletedDocumentForOther(); + + void moveFile(String bucketName, String oldPath, String newPath); + + void deleteDelegationfromS3(UserCompanyDelegationEntity userCompanyDelegationEntity); + + void deleteFileFromS3(DocumentEntity documentEntity, Long callId, Long applicationId); + } \ No newline at end of file diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/AmazonS3ServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/AmazonS3ServiceImpl.java index 56141be2..5e7624ac 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/AmazonS3ServiceImpl.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/AmazonS3ServiceImpl.java @@ -1,10 +1,17 @@ package net.gepafin.tendermanagement.service.impl; +import com.amazonaws.AmazonServiceException; +import com.amazonaws.SdkClientException; import com.amazonaws.services.s3.AmazonS3; +import com.amazonaws.services.s3.AmazonS3Client; import com.amazonaws.services.s3.model.*; import net.gepafin.tendermanagement.config.Translator; import net.gepafin.tendermanagement.constants.GepafinConstant; +import net.gepafin.tendermanagement.dao.S3PathConfig; +import net.gepafin.tendermanagement.entities.DocumentEntity; +import net.gepafin.tendermanagement.entities.UserCompanyDelegationEntity; +import net.gepafin.tendermanagement.enums.DocOtherSourceTypeEnum; import net.gepafin.tendermanagement.model.response.UploadFileOnAmazonS3Response; import net.gepafin.tendermanagement.service.AmazonS3Service; import net.gepafin.tendermanagement.util.Utils; @@ -45,6 +52,18 @@ public class AmazonS3ServiceImpl implements AmazonS3Service { @Value("${aws.s3.url}") private String s3Url; + @Autowired + private S3PathConfig s3ConfigBean; + + @Autowired + private AmazonS3Client s3Client; + + @Value("${aws.s3.region}") + private String region; + + private String getBucketUrlPrefix() { + return "https://" + bucketName + ".s3." + region + ".amazonaws.com/"; + } private String upload(String fileName, String s3Folder, MultipartFile file) throws IOException { @@ -125,4 +144,86 @@ public class AmazonS3ServiceImpl implements AmazonS3Service { Translator.toLocale(GepafinConstant.UPLOAD_ERROR_S3)); } } + + @Override + public String generateS3PathForDeletedDocument(DocOtherSourceTypeEnum typeOfDocument, Long callId, Long applicationId) { + try { + return s3ConfigBean.generateDocumentPathForOther(typeOfDocument, callId, applicationId); + } catch (IllegalArgumentException e) { + throw new CustomValidationException( + Status.VALIDATION_ERROR, + Translator.toLocale(GepafinConstant.S3_PATH_GENERATION_ERROR_MSG) + ); + } + } + + @Override + public String generateS3PathForDeletedDocumentForOther() { + try { + return s3ConfigBean.generateDocumentPathForDelegationAndSignedDocument(DocOtherSourceTypeEnum.DELETED_USER_DELEGATION); + } catch (IllegalArgumentException e) { + throw new CustomValidationException( + Status.VALIDATION_ERROR, + Translator.toLocale(GepafinConstant.S3_PATH_GENERATION_ERROR_MSG) + ); + } + } + + @Override + public void moveFile(String bucketName, String oldPath, String newPath) { + try { + log.info("Moving file from {} to {} in bucket {}", oldPath, newPath, bucketName); + + CopyObjectRequest copyRequest = new CopyObjectRequest(bucketName, oldPath, bucketName, newPath); + s3Client.copyObject(copyRequest); + log.info("File copied successfully from {} to {}", oldPath, newPath); + + s3Client.deleteObject(bucketName, oldPath); + log.info("Original file deleted successfully: {}", oldPath); + } catch (AmazonServiceException e) { + log.error("AWS service error while moving file: {}", e.getErrorMessage(), e); + throw e; + } catch (SdkClientException e) { + log.error("SDK client error while moving file: {}", e.getMessage(), e); + throw e; + } catch (Exception e) { + log.error("Unexpected error while moving file: {}", e.getMessage(), e); + throw e; + } + } + + @Override + public void deleteDelegationfromS3(UserCompanyDelegationEntity userCompanyDelegationEntity) { + String oldS3Path = userCompanyDelegationEntity.getFilePath(); + String newS3Path = generateS3PathForDeletedDocumentForOther() + + "/" + oldS3Path.substring(oldS3Path.lastIndexOf("/") + 1); + + String bucketUrlPrefix = getBucketUrlPrefix(); + if (oldS3Path.startsWith(bucketUrlPrefix)) { + oldS3Path = oldS3Path.replace(bucketUrlPrefix, ""); + } + moveFile(bucketName, oldS3Path, newS3Path); + log.info("File for company ID {} successfully moved to deleted folder.", userCompanyDelegationEntity.getId()); + } + + @Override + public void deleteFileFromS3(DocumentEntity documentEntity, Long callId, Long applicationId) { + try { + String oldS3Path = documentEntity.getFilePath(); + String newS3Path = generateS3PathForDeletedDocument(DocOtherSourceTypeEnum.valueOf("DELETED_" + documentEntity.getSource().toUpperCase()), callId, applicationId) + + "/" + oldS3Path.substring(oldS3Path.lastIndexOf("/") + 1); + String bucketUrlPrefix = getBucketUrlPrefix(); + if (oldS3Path.startsWith(bucketUrlPrefix)) { + oldS3Path = oldS3Path.replace(bucketUrlPrefix, ""); + } + + moveFile(bucketName, oldS3Path, newS3Path); + log.info("File for document ID {} successfully moved to deleted folder.", documentEntity.getId()); + } catch (Exception e) { + log.error("Error moving file for document ID {} to deleted folder: {}", documentEntity.getId(), e.getMessage()); + throw new CustomValidationException(Status.VALIDATION_ERROR, "Error occurred while moving file to deleted folder."); + } + } + + } \ No newline at end of file From 6d2374c3e6ba65c6af93c398673945198f700743 Mon Sep 17 00:00:00 2001 From: rajesh Date: Tue, 26 Nov 2024 19:23:12 +0530 Subject: [PATCH 32/43] Done ticket GEPAFINBE-104 --- .../tendermanagement/dao/ApplicationDao.java | 61 +++++++++-------- .../dao/AssignedApplicationsDao.java | 8 ++- .../dao/BeneficiaryPreferredCallDao.java | 25 +++++-- .../gepafin/tendermanagement/dao/CallDao.java | 14 ++-- .../tendermanagement/dao/CompanyDao.java | 68 ++++++++++++------- .../tendermanagement/dao/DashboardDao.java | 8 ++- .../tendermanagement/dao/DelegationDao.java | 26 ++++--- .../dao/EmailNotificationDao.java | 16 +++-- .../gepafin/tendermanagement/dao/FaqDao.java | 21 ++++-- .../tendermanagement/dao/FlowFormDao.java | 15 ++-- .../gepafin/tendermanagement/dao/PdfDao.java | 2 +- .../entities/ApplicationEntity.java | 11 +-- .../BeneficiaryPreferredCallEntity.java | 5 ++ .../tendermanagement/entities/FaqEntity.java | 4 ++ .../entities/UserCompanyDelegationEntity.java | 7 +- .../BeneficiaryPreferredCallResponseBean.java | 1 + .../repositories/ApplicationRepository.java | 10 +-- .../BeneficiaryPreferredCallRepository.java | 13 ++-- .../repositories/FaqRepository.java | 4 +- .../UserCompanyDelegationRepository.java | 2 +- .../service/CompanyService.java | 4 +- .../service/impl/ApplicationServiceImpl.java | 2 +- .../service/impl/CompanyServiceImpl.java | 5 +- .../db/changelog/db.changelog-1.0.0.xml | 23 +++++++ 24 files changed, 240 insertions(+), 115 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java index 017870ed..e1568a48 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java @@ -145,13 +145,16 @@ public class ApplicationDao { @Autowired private EmailLogDao emailLogDao; + + @Autowired + private UserWithCompanyRepository userWithCompanyRepository; public ApplicationResponseBean createApplication(HttpServletRequest request, ApplicationRequestBean applicationRequestBean, Long formId, Long applicationId) { FormEntity formEntity = formService.validateForm(formId); // callService.validatePublishedCall(formEntity.getCall().getId()); validateFormFields(applicationRequestBean,formEntity); ApplicationEntity applicationEntity = validateApplication(applicationId); - validator.validateUserWithCompany(request, applicationEntity.getCompany().getId()); + validator.validateUserWithCompany(request, applicationEntity.getCompanyId()); if(Boolean.FALSE.equals(applicationEntity.getStatus().equals(ApplicationStatusTypeEnum.DRAFT.getValue()))) { throw new CustomValidationException(Status.BAD_REQUEST,Translator.toLocale(GepafinConstant.APPLICATION_NOT_IN_DRAFT_STATUS)); } @@ -160,11 +163,10 @@ public class ApplicationDao { createOrUpdateMultipleFormFields(applicationRequestBean.getFormFields(), applicationFormEntity, formEntity); return getApplicationById(applicationEntity.getId(),formEntity.getId()); } - public void validateDelegation(UserEntity user, CompanyEntity company) { - UserWithCompanyEntity userWithCompany = companyService.getUserWithCompanyEntity(user.getId(), company.getId()); + public void validateDelegation(UserEntity user, UserWithCompanyEntity userWithCompany) { UserCompanyDelegationEntity userCompanyDelegationEntity = userCompanyDelegationRepository - .findByUserIdAndCompanyIdAndStatus(user.getId(), company.getId(), + .findByUserIdAndUserWithCompanyIdAndStatus(user.getId(), userWithCompany.getId(), UserCompanyDelegationStatusEnum.ACTIVE.getValue()); if (!userWithCompany.getIsLegalRepresentant() && userCompanyDelegationEntity == null) { @@ -187,13 +189,14 @@ public class ApplicationDao { return applicationFormEntity; } - public ApplicationEntity createApplicationEntity(UserEntity user, CallEntity call, CompanyEntity companyEntity) { - validateDelegation(user,companyEntity); + public ApplicationEntity createApplicationEntity(UserEntity user, CallEntity call, UserWithCompanyEntity userWithCompany) { + validateDelegation(user,userWithCompany); ApplicationEntity entity = new ApplicationEntity(); entity.setUserId(user.getId()); - entity.setCompany(companyEntity); + entity.setCompanyId(userWithCompany.getCompanyId()); entity.setCall(call); entity.setHubId(call.getHub().getId()); + entity.setUserWithCompany(userWithCompany); entity.setIsDeleted(false); entity.setStatus(ApplicationStatusTypeEnum.DRAFT.getValue()); return entity; @@ -262,7 +265,7 @@ public class ApplicationDao { log.info("Deleting application with ID: {}", id); ApplicationEntity applicationEntity= validateApplication(id); - validator.validateUserWithCompany(request, applicationEntity.getCompany().getId()); + validator.validateUserWithCompany(request, applicationEntity.getCompanyId()); applicationEntity.setIsDeleted(true); applicationEntity=saveApplicationEntity(applicationEntity); log.info("Application deleted with ID: {}", id); @@ -328,9 +331,9 @@ public class ApplicationDao { if (callId != null) { predicate = builder.and(predicate, builder.equal(root.get("call").get("id"), callId)); } - if (companyId != null) { - predicate = builder.and(predicate, builder.equal(root.get("company").get("id"), companyId)); - } + if (companyId != null) { + predicate = builder.and(predicate, builder.equal(root.get("companyId"), companyId)); + } if (statusList != null && !statusList.isEmpty()) { List statusNames = statusList.stream() .map(Enum::name) @@ -361,8 +364,9 @@ public class ApplicationDao { responseBean.setSubmissionDate(applicationEntity.getSubmissionDate()); responseBean.setStatus(applicationEntity.getStatus()); responseBean.setComments(applicationEntity.getComments()); - responseBean.setCompanyId(applicationEntity.getCompany().getId()); - responseBean.setCompanyName(applicationEntity.getCompany().getCompanyName()); + responseBean.setCompanyId(applicationEntity.getCompanyId()); + CompanyEntity company=companyService.validateCompany(applicationEntity.getCompanyId()); + responseBean.setCompanyName(company.getCompanyName()); if(applicationEntity.getProtocol() != null) { responseBean.setProtocolNumber(applicationEntity.getProtocol().getProtocolNumber()); } @@ -701,11 +705,12 @@ public class ApplicationDao { applicationGetResponseBean.setSubmissionDate(applicationEntity.getSubmissionDate()); applicationGetResponseBean.setCallId(applicationEntity.getCall().getId()); applicationGetResponseBean.setCallTitle(applicationEntity.getCall().getName()); - applicationGetResponseBean.setCompanyId(applicationEntity.getCompany().getId()); + applicationGetResponseBean.setCompanyId(applicationEntity.getCompanyId()); if(applicationEntity.getProtocol() != null) { applicationGetResponseBean.setProtocolNumber(applicationEntity.getProtocol().getProtocolNumber()); } - applicationGetResponseBean.setCompanyName(applicationEntity.getCompany().getCompanyName()); + CompanyEntity company=companyService.validateCompany(applicationEntity.getCompanyId()); + applicationGetResponseBean.setCompanyName(company.getCompanyName()); return applicationGetResponseBean; } @@ -722,16 +727,18 @@ public class ApplicationDao { public ApplicationResponse createApplicationByCallId(CompanyEntity companyEntity, ApplicationRequest applicationRequest, Long callId, UserEntity userEntity) { CallEntity call = callService.validateCall(callId); + UserWithCompanyEntity userWithCompanyEntity=companyService.getUserWithCompany(userEntity.getId(),companyEntity.getId()); + // call = callService.validatePublishedCall(call.getId()); - checkIfApplicationExists(call, companyEntity, userEntity); - ApplicationEntity applicationEntity = createApplicationEntity(userEntity, call, companyEntity); + checkIfApplicationExists(call, userWithCompanyEntity, userEntity); + ApplicationEntity applicationEntity = createApplicationEntity(userEntity, call, userWithCompanyEntity); applicationEntity.setComments(applicationRequest.getComments()); applicationEntity = saveApplicationEntity(applicationEntity); ApplicationResponse applicationResponse = getApplicationResponse(applicationEntity); return applicationResponse; } - public void checkIfApplicationExists(CallEntity call, CompanyEntity companyEntity, UserEntity userEntity){ - Optional applicationEntity=applicationRepository.findByUserIdAndCompanyIdAndCallIdAndIsDeletedFalse(userEntity.getId(), companyEntity.getId(),call.getId()); + public void checkIfApplicationExists(CallEntity call, UserWithCompanyEntity userWithCompanyEntity, UserEntity userEntity){ + Optional applicationEntity=applicationRepository.findByUserIdAndUserWithCompanyIdAndCallIdAndIsDeletedFalse(userEntity.getId(), userWithCompanyEntity.getId(),call.getId()); if(applicationEntity.isPresent()){ throw new CustomValidationException(Status.BAD_REQUEST,Translator.toLocale(GepafinConstant.APPLICATION_ALREADY_EXISTS)); } @@ -740,7 +747,7 @@ public class ApplicationDao { public ApplicationResponse updateApplicationStatus(HttpServletRequest request, Long applicationId, ApplicationStatusTypeEnum status) { ApplicationEntity applicationEntity = validateApplication(applicationId); UserEntity userEntity = userService.validateUser(applicationEntity.getUserId()); - validator.validateUserWithCompany(request, applicationEntity.getCompany().getId()); + validator.validateUserWithCompany(request, applicationEntity.getCompanyId()); if (ApplicationStatusTypeEnum.SUBMIT.getValue().equals(applicationEntity.getStatus())) { throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.APPLICATION_SUBMITTED_CANNOT_CHANGE)); } @@ -846,7 +853,7 @@ public class ApplicationDao { private void sendMailToUserAndCompany(UserEntity userEntity, ApplicationEntity applicationEntity) { CallEntity call =applicationEntity.getCall(); - CompanyEntity company = applicationEntity.getCompany(); + CompanyEntity company=companyService.validateCompany(applicationEntity.getCompanyId()); ProtocolEntity protocol = applicationEntity.getProtocol(); HubEntity hub = hubService.valdateHub(applicationEntity.getHubId()); SystemEmailTemplateResponse systemEmailTemplateResponse = systemEmailTemplatesService @@ -889,7 +896,7 @@ public class ApplicationDao { recipientEmails.add(contactEmail); } if(Boolean.FALSE.equals(recipientEmails.isEmpty())){ - emailLogRequest.setRecipientId(applicationEntity.getCompany().getId()); + emailLogRequest.setRecipientId(applicationEntity.getCompanyId()); emailLogRequest.setRecipientType(RecipientTypeEnum.COMPANY); emailLogRequest.setRecipientEmails(companyEmail); } @@ -897,7 +904,7 @@ public class ApplicationDao { } private void sendMailTodefaultSystemAndGepafin(UserEntity userEntity, ApplicationEntity applicationEntity) { CallEntity call = applicationEntity.getCall(); - CompanyEntity company = applicationEntity.getCompany(); + CompanyEntity company=companyService.validateCompany(applicationEntity.getCompanyId()); ProtocolEntity protocol = applicationEntity.getProtocol(); HubEntity hub = hubService.valdateHub(applicationEntity.getHubId()); SystemEmailTemplateResponse systemEmailTemplateResponse = systemEmailTemplatesService @@ -941,7 +948,7 @@ public class ApplicationDao { public ApplicationSignedDocumentResponse uploadSignedDocument(HttpServletRequest request, Long applicationId, MultipartFile file) { ApplicationEntity applicationEntity = validateApplication(applicationId); - validator.validateUserWithCompany(request, applicationEntity.getCompany().getId()); + validator.validateUserWithCompany(request, applicationEntity.getCompanyId()); validateFileTypeForCall(file, applicationEntity); ApplicationSignedDocumentEntity applicationSignedDocument = applicationSignedDocumentRepository .findByApplicationIdAndStatus(applicationId, ApplicationSignedDocumentStatusEnum.ACTIVE.getValue()); @@ -1017,7 +1024,7 @@ public class ApplicationDao { public ApplicationSignedDocumentResponse getSignedDocument(HttpServletRequest request, Long applicationId) { ApplicationEntity applicationEntity = validateApplication(applicationId); - validator.validateUserWithCompany(request, applicationEntity.getCompany().getId()); + validator.validateUserWithCompany(request, applicationEntity.getCompanyId()); ApplicationSignedDocumentEntity applicationSignedDocument = applicationSignedDocumentRepository .findByApplicationIdAndStatus(applicationId, ApplicationSignedDocumentStatusEnum.ACTIVE.getValue()); @@ -1030,7 +1037,7 @@ public class ApplicationDao { public void deleteSignedDocument(HttpServletRequest request, Long applicationId) { ApplicationEntity applicationEntity = validateApplication(applicationId); - validator.validateUserWithCompany(request, applicationEntity.getCompany().getId()); + validator.validateUserWithCompany(request, applicationEntity.getCompanyId()); ApplicationSignedDocumentEntity applicationSignedDocument = applicationSignedDocumentRepository .findByApplicationIdAndStatus(applicationId, ApplicationSignedDocumentStatusEnum.ACTIVE.getValue()); @@ -1045,7 +1052,7 @@ public class ApplicationDao { public ApplicationResponse validateApplication(HttpServletRequest request, Long applicationId) { ApplicationEntity applicationEntity = validateApplication(applicationId); UserEntity userEntity = userService.validateUser(applicationEntity.getUserId()); - validator.validateUserWithCompany(request, applicationEntity.getCompany().getId()); + validator.validateUserWithCompany(request, applicationEntity.getCompanyId()); if (Boolean.FALSE.equals(ApplicationStatusTypeEnum.DRAFT.getValue().equals(applicationEntity.getStatus()))) { throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.APPLICATION_NOT_IN_DRAFT_STATUS)); } diff --git a/src/main/java/net/gepafin/tendermanagement/dao/AssignedApplicationsDao.java b/src/main/java/net/gepafin/tendermanagement/dao/AssignedApplicationsDao.java index 1617b3e7..e3443f7d 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/AssignedApplicationsDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/AssignedApplicationsDao.java @@ -5,6 +5,7 @@ import net.gepafin.tendermanagement.config.Translator; import net.gepafin.tendermanagement.constants.GepafinConstant; import net.gepafin.tendermanagement.entities.ApplicationEntity; import net.gepafin.tendermanagement.entities.AssignedApplicationsEntity; +import net.gepafin.tendermanagement.entities.CompanyEntity; import net.gepafin.tendermanagement.entities.UserEntity; import net.gepafin.tendermanagement.enums.ApplicationStatusTypeEnum; import net.gepafin.tendermanagement.enums.AssignedApplicationEnum; @@ -14,6 +15,7 @@ import net.gepafin.tendermanagement.model.response.AssignedApplicationsResponse; import net.gepafin.tendermanagement.repositories.ApplicationRepository; import net.gepafin.tendermanagement.repositories.AssignedApplicationsRepository; import net.gepafin.tendermanagement.service.ApplicationService; +import net.gepafin.tendermanagement.service.CompanyService; import net.gepafin.tendermanagement.service.UserService; import net.gepafin.tendermanagement.util.DateTimeUtil; import net.gepafin.tendermanagement.util.Validator; @@ -50,6 +52,9 @@ public class AssignedApplicationsDao { private Validator validator; @Autowired private ApplicationEvaluationDao applicationEvaluationDao; + + @Autowired + private CompanyService companyService; public AssignedApplicationsResponse createAssignedApplications(Long applicationId, Long userId, UserEntity assignedByUser, AssignedApplicationsRequest assignedApplicationsRequest){ log.info("Assigning application to pre-Instructor with details: {}", applicationId,userId); @@ -131,7 +136,8 @@ public class AssignedApplicationsDao { assignedApplicationsResponse.setAssignedAt(assignedApplications.getAssignedAt()); assignedApplicationsResponse.setProtocolNumber(protocolNumber); assignedApplicationsResponse.setCallName(callName); - assignedApplicationsResponse.setCompanyName(application.getCompany().getCompanyName()); + CompanyEntity company=companyService.validateCompany(application.getCompanyId()); + assignedApplicationsResponse.setCompanyName(company.getCompanyName()); assignedApplicationsResponse.setBeneficiaryName(beneficiaryName); assignedApplicationsResponse.setSubmissionDate(submissionDate); assignedApplicationsResponse.setCallEndDate(callEndDate); diff --git a/src/main/java/net/gepafin/tendermanagement/dao/BeneficiaryPreferredCallDao.java b/src/main/java/net/gepafin/tendermanagement/dao/BeneficiaryPreferredCallDao.java index 60f8ea20..5e4df57f 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/BeneficiaryPreferredCallDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/BeneficiaryPreferredCallDao.java @@ -4,11 +4,14 @@ import net.gepafin.tendermanagement.config.Translator; import net.gepafin.tendermanagement.constants.GepafinConstant; import net.gepafin.tendermanagement.entities.BeneficiaryPreferredCallEntity; import net.gepafin.tendermanagement.entities.UserEntity; +import net.gepafin.tendermanagement.entities.UserWithCompanyEntity; import net.gepafin.tendermanagement.enums.BeneficiaryCallStatus; import net.gepafin.tendermanagement.model.request.BeneficiaryPreferredCallReq; import net.gepafin.tendermanagement.model.response.BeneficiaryPreferredCallResponseBean; import net.gepafin.tendermanagement.repositories.BeneficiaryPreferredCallRepository; +import net.gepafin.tendermanagement.repositories.UserWithCompanyRepository; +import net.gepafin.tendermanagement.service.CompanyService; import net.gepafin.tendermanagement.util.Validator; import net.gepafin.tendermanagement.web.rest.api.errors.CustomValidationException; import net.gepafin.tendermanagement.web.rest.api.errors.ResourceNotFoundException; @@ -36,26 +39,32 @@ public class BeneficiaryPreferredCallDao { @Autowired private Validator validator; + @Autowired + private UserWithCompanyRepository userWithCompanyRepository; + + @Autowired + private CompanyService companyService; + public BeneficiaryPreferredCallResponseBean createBeneficiaryPreferredCall(HttpServletRequest httpServletRequest, BeneficiaryPreferredCallReq request, UserEntity user) { log.info("Creating new beneficiary preferred call with details: {}", request); validator.validateUserWithCompany(httpServletRequest, request.getCompanyId()); - + UserWithCompanyEntity userWithCompanyEntity=companyService.getUserWithCompany(user.getId(), request.getCompanyId()); Optional existingCall = beneficiaryPreferredCallRepository - .findByUserIdAndCallIdAndCompanyIdAndIsDeletedFalse(user.getId(), request.getCallId(), request.getCompanyId()); + .findByUserIdAndCallIdAndUserWithCompanyIdAndIsDeletedFalse(user.getId(), request.getCallId(), userWithCompanyEntity.getId()); if (existingCall.isPresent()) { log.warn("Duplicate beneficiary preferred call detected: {}", existingCall.get()); throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.DUPLICATE_BENEFICIARY_CALL)); } - BeneficiaryPreferredCallEntity entity = convertRequestToEntity(request, user); + BeneficiaryPreferredCallEntity entity = convertRequestToEntity(request, user,userWithCompanyEntity); entity = beneficiaryPreferredCallRepository.save(entity); log.info("Beneficiary preferred call created with ID: {}", entity.getId()); return convertEntityToResponse(entity); } - private BeneficiaryPreferredCallEntity convertRequestToEntity(BeneficiaryPreferredCallReq request,UserEntity userEntity) { + private BeneficiaryPreferredCallEntity convertRequestToEntity(BeneficiaryPreferredCallReq request,UserEntity userEntity,UserWithCompanyEntity userWithCompanyEntity) { BeneficiaryPreferredCallEntity entity = new BeneficiaryPreferredCallEntity(); if (userEntity.getBeneficiary()!=null) { entity.setBeneficiaryId(userEntity.getBeneficiary().getId()); @@ -63,7 +72,8 @@ public class BeneficiaryPreferredCallDao { entity.setStatus(BeneficiaryCallStatus.ENABLED.getValue()); entity.setCallId(request.getCallId()); entity.setUserId(userEntity.getId()); - entity.setCompanyId(request.getCompanyId()); + entity.setCompanyId(userWithCompanyEntity.getCompanyId()); + entity.setUserWithCompany(userWithCompanyEntity); entity.setIsDeleted( false); return entity; } @@ -122,6 +132,7 @@ public class BeneficiaryPreferredCallDao { response.setCallId(entity.getCallId()); response.setUserId(entity.getUserId()); response.setCompanyId(entity.getCompanyId()); + response.setUserWithCompanyId(entity.getUserWithCompany().getId()); response.setCreatedDate(entity.getCreatedDate()); response.setUpdatedDate(entity.getUpdatedDate()); @@ -135,8 +146,8 @@ public class BeneficiaryPreferredCallDao { log.info("Beneficiary preferred call status updated with ID: {}", existingEntity.getId()); } public List getBeneficiaryPreferredCallByUserId(UserEntity userEntity, Long companyId) { - - List calls = beneficiaryPreferredCallRepository.findByUserIdAndCompanyIdAndIsDeletedFalse(userEntity.getId(), companyId); + UserWithCompanyEntity userWithCompanyEntity=companyService.getUserWithCompany(userEntity.getId(),companyId); + List calls = beneficiaryPreferredCallRepository.findByUserIdAndUserWithCompanyIdAndIsDeletedFalse(userEntity.getId(), userWithCompanyEntity.getId()); return calls.stream() .map(this::convertEntityToResponse) .collect(Collectors.toList()); diff --git a/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java b/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java index b19a50d2..697779fb 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java @@ -95,6 +95,9 @@ public class CallDao { @Autowired private Validator validator; + @Autowired + private CompanyService companyService; + public CallResponse createCallStep1(CreateCallRequestStep1 createCallRequest, UserEntity userEntity) { createCallRequest.setRegionId(userEntity.getRoleEntity().getRegion().getId()); @@ -433,8 +436,9 @@ public class CallDao { BeneficiaryPreferredCallEntity preferredCall; if (companyId != null) { validator.validateUserWithCompany(request, companyId); + UserWithCompanyEntity userWithCompanyEntity=companyService.getUserWithCompany(user.getId(),companyId); preferredCall = beneficiaryPreferredCallRepository - .findByUserIdAndCallIdAndCompanyIdAndIsDeletedFalse(userId, callId, companyId) + .findByUserIdAndCallIdAndUserWithCompanyIdAndIsDeletedFalse(userId, callId, userWithCompanyEntity.getId()) .orElse(null); } else { preferredCall = beneficiaryPreferredCallRepository @@ -670,8 +674,9 @@ public class CallDao { if (Boolean.TRUE.equals(onlyPreferredCall)) { validator.validateUserWithCompany(request, companyId); + UserWithCompanyEntity userWithCompanyEntity=companyService.getUserWithCompany(user.getId(),companyId); List preferredCalls = beneficiaryPreferredCallRepository - .findByUserIdAndCompanyIdAndIsDeletedFalse(user.getId(), companyId); + .findByUserIdAndUserWithCompanyIdAndIsDeletedFalse(user.getId(), userWithCompanyEntity.getId()); List preferredCallIds = preferredCalls.stream() .map(BeneficiaryPreferredCallEntity::getCallId) .collect(Collectors.toList()); @@ -699,10 +704,11 @@ public class CallDao { public Map getBeneficiaryPreferredCallsForUser(HttpServletRequest request, UserEntity user, List callIds, Long companyId) { List beneficiaryPreferredCalls; - if (companyId != null) { + if (companyId != null && Boolean.TRUE.equals(validator.checkIsBeneficiary())) { validator.validateUserWithCompany(request, companyId); + UserWithCompanyEntity userWithCompanyEntity=companyService.getUserWithCompany(user.getId(),companyId); beneficiaryPreferredCalls = beneficiaryPreferredCallRepository - .findByUserIdAndCallIdInAndCompanyIdAndIsDeletedFalse(user.getId(), callIds, companyId); + .findByUserIdAndCallIdInAndUserWithCompanyIdAndIsDeletedFalse(user.getId(), callIds, userWithCompanyEntity.getId()); } else { beneficiaryPreferredCalls = beneficiaryPreferredCallRepository .findByUserIdAndCallIdInAndIsDeletedFalse(user.getId(), callIds); diff --git a/src/main/java/net/gepafin/tendermanagement/dao/CompanyDao.java b/src/main/java/net/gepafin/tendermanagement/dao/CompanyDao.java index 84b01021..09d1319f 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/CompanyDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/CompanyDao.java @@ -1,11 +1,13 @@ package net.gepafin.tendermanagement.dao; +import java.util.EnumSet; import java.util.List; import net.gepafin.tendermanagement.entities.*; import net.gepafin.tendermanagement.enums.ApplicationStatusTypeEnum; -import net.gepafin.tendermanagement.repositories.ApplicationRepository; -import net.gepafin.tendermanagement.repositories.FaqRepository; +import net.gepafin.tendermanagement.enums.UserCompanyDelegationStatusEnum; +import net.gepafin.tendermanagement.repositories.*; +import net.gepafin.tendermanagement.service.CompanyService; import net.gepafin.tendermanagement.web.rest.api.errors.*; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; @@ -15,8 +17,6 @@ import net.gepafin.tendermanagement.config.Translator; import net.gepafin.tendermanagement.constants.GepafinConstant; import net.gepafin.tendermanagement.model.request.CompanyRequest; import net.gepafin.tendermanagement.model.response.CompanyResponse; -import net.gepafin.tendermanagement.repositories.CompanyRepository; -import net.gepafin.tendermanagement.repositories.UserWithCompanyRepository; import net.gepafin.tendermanagement.service.UserService; import net.gepafin.tendermanagement.util.Utils; @@ -37,6 +37,15 @@ public class CompanyDao { private ApplicationRepository applicationRepository; @Autowired private FaqRepository faqRepository; + + @Autowired + private BeneficiaryPreferredCallRepository beneficiaryPreferredCallRepository; + + @Autowired + private UserCompanyDelegationRepository userCompanyDelegationRepository; + + @Autowired + private CompanyService companyService; public CompanyResponse createCompany(UserEntity userEntity, CompanyRequest companyRequest) { @@ -200,27 +209,38 @@ public class CompanyDao { } public UserWithCompanyEntity getUserWithCompany(Long userId, Long compnayId) { - return userWithCompanyRepository.findByUserIdAndCompanyIdAndIsDeletedFalse(userId, compnayId).orElseThrow( - () -> new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.USER_COMPANY_RELATION_NOT_FOUND))); - } - public void removeCompanyFromList(UserEntity userEntity, Long companyId) { - CompanyEntity companyEntity = validateCompany(companyId); - UserWithCompanyEntity existingRelation = userWithCompanyRepository.findByUserIdAndCompanyIdAndIsDeletedFalse(userEntity.getId(), companyEntity.getId()) - .orElseThrow(() -> new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.USER_ALREADY_CONNECTED_TO_COMPANY))); - List userApplications = applicationRepository.findByCompanyIdAndUserIdAndIsDeletedFalse(companyEntity.getId(), userEntity.getId()); - List faqs = faqRepository.findByCompanyIdAndUserIdAndIsDeletedFalse(companyEntity.getId(), userEntity.getId()); - for (ApplicationEntity application : userApplications) { - if(Boolean.TRUE.equals(application.getStatus().equals(ApplicationStatusTypeEnum.SUBMIT.getValue()))) { - throw new CustomValidationException(Status.BAD_REQUEST,Translator.toLocale(GepafinConstant.CANNOT_DELETE_COMPANY_WITH_APPLICATION_SUBMITT)); - } - if(Boolean.TRUE.equals(application.getStatus().equals(ApplicationStatusTypeEnum.DRAFT.getValue()))) { - application.setIsDeleted(Boolean.TRUE); - applicationRepository.save(application); - } + return userWithCompanyRepository.findByUserIdAndCompanyIdAndIsDeletedFalse(userId, compnayId).orElseThrow( + () -> new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.USER_COMPANY_RELATION_NOT_FOUND))); } - for(FaqEntity faq:faqs) { - faq.setIsDeleted(Boolean.TRUE); - faqRepository.save(faq); + public void removeCompanyFromList(UserEntity userEntity, Long companyId) { + CompanyEntity companyEntity = validateCompany(companyId); + UserWithCompanyEntity existingRelation=companyService.getUserWithCompany(userEntity.getId(),companyEntity.getId()); + List userApplications = applicationRepository.findByUserWithCompanyIdAndUserIdAndIsDeletedFalse(existingRelation.getId(), userEntity.getId()); + List faqs = faqRepository.findByUserWithCompanyIdAndIsDeletedFalse(existingRelation.getId()); + List preferredCallEntities= beneficiaryPreferredCallRepository.findByUserIdAndUserWithCompanyIdAndIsDeletedFalse(userEntity.getId(),existingRelation.getId()); + UserCompanyDelegationEntity userCompanyDelegationEntity = userCompanyDelegationRepository.findByUserIdAndUserWithCompanyIdAndStatus(userEntity.getId(),existingRelation.getId(), UserCompanyDelegationStatusEnum.ACTIVE.getValue()); + List applicationStatusAllowed = List.of( + ApplicationStatusTypeEnum.DRAFT.getValue(), + ApplicationStatusTypeEnum.AWAITING.getValue(), + ApplicationStatusTypeEnum.READY.getValue() + ); + boolean notAllowedStatus = userApplications.stream() + .anyMatch(application -> !applicationStatusAllowed.contains(application.getStatus())); + if (notAllowedStatus) { + throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.CANNOT_DELETE_COMPANY_WITH_APPLICATION_SUBMITT)); + } + userApplications + .forEach(application -> application.setIsDeleted(Boolean.TRUE)); + applicationRepository.saveAll(userApplications); + faqs.forEach(faq -> faq.setIsDeleted(Boolean.TRUE)); + faqRepository.saveAll(faqs); + + preferredCallEntities.forEach(preferredCall -> preferredCall.setIsDeleted(Boolean.TRUE)); + beneficiaryPreferredCallRepository.saveAll(preferredCallEntities); + + if(userCompanyDelegationEntity!=null){ + userCompanyDelegationEntity.setStatus( UserCompanyDelegationStatusEnum.INACTIVE.getValue()); + userCompanyDelegationRepository.save(userCompanyDelegationEntity); } existingRelation.setIsDeleted(Boolean.TRUE); userWithCompanyRepository.save(existingRelation); diff --git a/src/main/java/net/gepafin/tendermanagement/dao/DashboardDao.java b/src/main/java/net/gepafin/tendermanagement/dao/DashboardDao.java index c76d14c9..0afc8fc8 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/DashboardDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/DashboardDao.java @@ -2,6 +2,7 @@ package net.gepafin.tendermanagement.dao; import net.gepafin.tendermanagement.entities.CompanyEntity; import net.gepafin.tendermanagement.entities.UserEntity; +import net.gepafin.tendermanagement.entities.UserWithCompanyEntity; import net.gepafin.tendermanagement.enums.CallStatusEnum; import net.gepafin.tendermanagement.enums.RoleStatusEnum; import net.gepafin.tendermanagement.enums.UserStatusEnum; @@ -12,6 +13,7 @@ import net.gepafin.tendermanagement.repositories.ApplicationRepository; import net.gepafin.tendermanagement.repositories.CallRepository; import net.gepafin.tendermanagement.repositories.CompanyRepository; import net.gepafin.tendermanagement.repositories.UserRepository; +import net.gepafin.tendermanagement.service.CompanyService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -31,6 +33,9 @@ public class DashboardDao { @Autowired private CompanyRepository companyRepository; + + @Autowired + private CompanyService companyService; public SuperAdminWidgetResponseBean getDashboardWidget(UserEntity requestedUserEntity) { SuperAdminWidgetResponseBean widgetResponseBean = new SuperAdminWidgetResponseBean(); @@ -108,8 +113,9 @@ public class DashboardDao { if (activeCalls != null) { beneficiaryWidgetResponseBean.setNumberOfCalls(activeCalls); } + UserWithCompanyEntity userWithCompanyEntity=companyService.getUserWithCompany(userEntity.getId(),company.getId()); Long activeApplication = applicationRepository.countSubmittedApplicationsByUserId(userEntity.getId(), - company.getId()); + userWithCompanyEntity.getId()); if (activeApplication != null) { beneficiaryWidgetResponseBean.setNumberOfApplications(activeApplication); } diff --git a/src/main/java/net/gepafin/tendermanagement/dao/DelegationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/DelegationDao.java index dfc65ec7..d6dfd057 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/DelegationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/DelegationDao.java @@ -5,10 +5,14 @@ import java.io.IOException; import java.io.InputStream; import java.util.HashMap; import java.util.Map; +import java.util.Optional; import java.util.function.Function; +import net.gepafin.tendermanagement.entities.*; import net.gepafin.tendermanagement.enums.DocOtherSourceTypeEnum; +import net.gepafin.tendermanagement.repositories.UserWithCompanyRepository; +import net.gepafin.tendermanagement.service.CompanyService; import org.apache.commons.lang3.StringUtils; import org.apache.poi.xwpf.usermodel.XWPFDocument; import org.springframework.beans.factory.annotation.Autowired; @@ -18,10 +22,6 @@ import org.springframework.web.multipart.MultipartFile; import jakarta.servlet.http.HttpServletRequest; import net.gepafin.tendermanagement.config.Translator; import net.gepafin.tendermanagement.constants.GepafinConstant; -import net.gepafin.tendermanagement.entities.CompanyEntity; -import net.gepafin.tendermanagement.entities.DocumentEntity; -import net.gepafin.tendermanagement.entities.UserCompanyDelegationEntity; -import net.gepafin.tendermanagement.entities.UserEntity; import net.gepafin.tendermanagement.enums.UserCompanyDelegationStatusEnum; import net.gepafin.tendermanagement.model.request.CompanyDelegationRequest; import net.gepafin.tendermanagement.model.response.CompanyDelegationResponse; @@ -67,6 +67,12 @@ public class DelegationDao { @Autowired private Validator validator; + @Autowired + private UserWithCompanyRepository userWithCompanyRepository; + + @Autowired + private CompanyService companyService; + public ByteArrayOutputStream generateDocument(Map placeholders, String templateName) { try { String s3Folder = s3ConfigBean.generateDocumentPathForOther(DocOtherSourceTypeEnum.TEMPLATE, 0L, 0L); @@ -182,8 +188,9 @@ public class DelegationDao { companyDao.validateCompany(companyId); companyDao.getUserWithCompany(userEntity.getId(), companyId); validateFileType(file); + UserWithCompanyEntity userWithCompanyEntity=companyService.getUserWithCompany(userEntity.getId(),companyId); UserCompanyDelegationEntity userCompanyDelegationEntity = userCompanyDelegationRepository - .findByUserIdAndCompanyIdAndStatus(userEntity.getId(), companyId, + .findByUserIdAndUserWithCompanyIdAndStatus(userEntity.getId(), userWithCompanyEntity.getId(), UserCompanyDelegationStatusEnum.ACTIVE.getValue()); if (userCompanyDelegationEntity != null) { userCompanyDelegationEntity.setStatus(UserCompanyDelegationStatusEnum.INACTIVE.getValue()); @@ -191,7 +198,8 @@ public class DelegationDao { } UploadFileOnAmazonS3Response uploadFileOnAmazonS3Response = uploadFileOnAmazonS3ForCompanyDelegation(file); userCompanyDelegationEntity = new UserCompanyDelegationEntity(); - userCompanyDelegationEntity.setCompanyId(companyId); + userCompanyDelegationEntity.setUserWithCompany(userWithCompanyEntity); + userCompanyDelegationEntity.setCompanyId(userWithCompanyEntity.getCompanyId()); userCompanyDelegationEntity.setUserId(userEntity.getId()); if (userEntity.getBeneficiary() != null) { userCompanyDelegationEntity.setBeneficiaryId(userEntity.getBeneficiary().getId()); @@ -235,8 +243,9 @@ public class DelegationDao { } public CompanyDelegationResponse getCompanyDelegation(UserEntity userEntity, Long companyId) { + UserWithCompanyEntity userWithCompanyEntity=companyService.getUserWithCompany(userEntity.getId(),companyId); UserCompanyDelegationEntity userCompanyDelegationEntity = userCompanyDelegationRepository - .findByUserIdAndCompanyIdAndStatus(userEntity.getId(), companyId, + .findByUserIdAndUserWithCompanyIdAndStatus(userEntity.getId(), userWithCompanyEntity.getId(), UserCompanyDelegationStatusEnum.ACTIVE.getValue()); companyDao.getUserWithCompany(userEntity.getId(), companyId); if(userCompanyDelegationEntity == null) { @@ -247,8 +256,9 @@ public class DelegationDao { } public void deleteCompanyDelegation(UserEntity userEntity, Long companyId) { + UserWithCompanyEntity userWithCompanyEntity=companyService.getUserWithCompany(userEntity.getId(),companyId); UserCompanyDelegationEntity userCompanyDelegationEntity = userCompanyDelegationRepository - .findByUserIdAndCompanyIdAndStatus(userEntity.getId(), companyId, + .findByUserIdAndUserWithCompanyIdAndStatus(userEntity.getId(), userWithCompanyEntity.getId(), UserCompanyDelegationStatusEnum.ACTIVE.getValue()); companyDao.getUserWithCompany(userEntity.getId(), companyId); if(userCompanyDelegationEntity == null) { diff --git a/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java index 2f193047..baa260ed 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java @@ -14,10 +14,7 @@ import net.gepafin.tendermanagement.model.request.EmailLogRequest; import net.gepafin.tendermanagement.model.response.SystemEmailTemplateResponse; import net.gepafin.tendermanagement.repositories.EmailLogRepository; import net.gepafin.tendermanagement.repositories.HubRepository; -import net.gepafin.tendermanagement.service.ApplicationService; -import net.gepafin.tendermanagement.service.HubService; -import net.gepafin.tendermanagement.service.SystemEmailTemplatesService; -import net.gepafin.tendermanagement.service.UserService; +import net.gepafin.tendermanagement.service.*; import net.gepafin.tendermanagement.service.impl.EmailService; import net.gepafin.tendermanagement.service.impl.EmailServiceFactory; import net.gepafin.tendermanagement.util.DateTimeUtil; @@ -58,6 +55,9 @@ public class EmailNotificationDao { @Autowired private EmailLogRepository emailLogRepository; + + @Autowired + private CompanyService companyService; private void sendEmail(ApplicationEntity applicationEntity, SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum templateType, @@ -69,8 +69,9 @@ public class EmailNotificationDao { SystemEmailTemplateResponse systemEmailTemplateResponse = systemEmailTemplatesService.retrieveTemplateByTypeAndCall(templateType, hubEntity, null); Map subjectPlaceholders = new HashMap<>(); + CompanyEntity company=companyService.validateCompany(applicationEntity.getCompanyId()); subjectPlaceholders.put("{{call_name}}", applicationEntity.getCall().getName()); - subjectPlaceholders.put("{{company_name}}", applicationEntity.getCompany().getCompanyName()); + subjectPlaceholders.put("{{company_name}}", company.getCompanyName()); bodyPlaceholders.put("{{legal_mail}}", legalMail); String subject = Utils.replacePlaceholders(systemEmailTemplateResponse.getSubject(), subjectPlaceholders); String body = Utils.replacePlaceholders(systemEmailTemplateResponse.getHtmlContent(), bodyPlaceholders); @@ -82,8 +83,9 @@ public class EmailNotificationDao { } private List getRecipientEmails(ApplicationEntity applicationEntity, UserEntity userEntity, List additionalRecipients) { List recipientEmails = new ArrayList<>(); - String companyEmail = applicationEntity.getCompany().getEmail(); - String contactEmail = applicationEntity.getCompany().getContactEmail(); + CompanyEntity company=companyService.validateCompany(applicationEntity.getCompanyId()); + String companyEmail = company.getEmail(); + String contactEmail = company.getContactEmail(); if (companyEmail != null && !companyEmail.isEmpty()) { recipientEmails.add(companyEmail); diff --git a/src/main/java/net/gepafin/tendermanagement/dao/FaqDao.java b/src/main/java/net/gepafin/tendermanagement/dao/FaqDao.java index cfec2fe2..4b388791 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/FaqDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/FaqDao.java @@ -2,15 +2,13 @@ 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.FaqEntity; -import net.gepafin.tendermanagement.entities.LookUpDataEntity; -import net.gepafin.tendermanagement.entities.UserEntity; +import net.gepafin.tendermanagement.entities.*; import net.gepafin.tendermanagement.enums.RoleStatusEnum; import net.gepafin.tendermanagement.entities.LookUpDataEntity.LookUpDataTypeEnum; import net.gepafin.tendermanagement.model.request.FaqReq; import net.gepafin.tendermanagement.model.response.FaqResponseBean; import net.gepafin.tendermanagement.repositories.FaqRepository; +import net.gepafin.tendermanagement.repositories.UserWithCompanyRepository; import net.gepafin.tendermanagement.service.CallService; import net.gepafin.tendermanagement.service.CompanyService; import net.gepafin.tendermanagement.service.LookUpDataService; @@ -26,6 +24,7 @@ import static net.gepafin.tendermanagement.util.Utils.setIfUpdated; import java.time.LocalDateTime; import java.util.List; +import java.util.Optional; @Component public class FaqDao { @@ -44,6 +43,9 @@ public class FaqDao { @Autowired private CompanyService companyService; + + @Autowired + private UserWithCompanyRepository userWithCompanyRepository; public FaqResponseBean createFaq(FaqReq faqRequest, UserEntity userEntity, Long callId, Long companyId) { CallEntity callEntity = callService.validateCall(callId); @@ -53,10 +55,15 @@ public class FaqDao { throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.COMPANY_ID_MANDATORY)); } - if(companyId!=null) { - companyService.validateCompany(companyId); - entity.setCompanyId(companyId); + UserWithCompanyEntity userWithCompanyEntity=null; + if(companyId!=null) { + userWithCompanyEntity=companyService.getUserWithCompany(userEntity.getId(),companyId); + companyService.validateCompany(userWithCompanyEntity.getCompanyId()); + entity.setCompanyId(userWithCompanyEntity.getCompanyId()); + } + + entity.setUserWithCompany(userWithCompanyEntity); faqRepository.save(entity); return convertToFaqResponseBean(entity); } diff --git a/src/main/java/net/gepafin/tendermanagement/dao/FlowFormDao.java b/src/main/java/net/gepafin/tendermanagement/dao/FlowFormDao.java index 4ad912f4..4a42daf7 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/FlowFormDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/FlowFormDao.java @@ -3,19 +3,15 @@ package net.gepafin.tendermanagement.dao; import java.util.*; import java.util.stream.Collectors; +import net.gepafin.tendermanagement.entities.*; import net.gepafin.tendermanagement.enums.ApplicationStatusTypeEnum; import net.gepafin.tendermanagement.repositories.*; +import net.gepafin.tendermanagement.service.CompanyService; 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.service.FormService; @@ -44,6 +40,8 @@ public class FlowFormDao { private FormService formService; @Autowired private FormDao formDao; + @Autowired + private CompanyService companyService; @@ -290,6 +288,7 @@ public class FlowFormDao { private NextOrPreviousFormResponse setNextOrPreviousResponse(Long calculatedFormId, ApplicationEntity applicationEntity) { NextOrPreviousFormResponse nextOrPreviousFormResponse = new NextOrPreviousFormResponse(); Integer completedSteps=0; + CompanyEntity company=companyService.validateCompany(applicationEntity.getCompanyId()); FormEntity formEntity = formService.validateForm(calculatedFormId); nextOrPreviousFormResponse.setFormId(calculatedFormId); nextOrPreviousFormResponse.setApplicationStatus(ApplicationStatusTypeEnum.valueOf(applicationEntity.getStatus())); @@ -297,8 +296,8 @@ public class FlowFormDao { applicationDao.processForm(formEntity, applicationEntity)); nextOrPreviousFormResponse.setCallId(applicationEntity.getCall().getId()); nextOrPreviousFormResponse.setCallTitle(applicationEntity.getCall().getName()); - nextOrPreviousFormResponse.setCompanyId(applicationEntity.getCompany().getId()); - nextOrPreviousFormResponse.setCompanyName(applicationEntity.getCompany().getCompanyName()); + nextOrPreviousFormResponse.setCompanyId(applicationEntity.getCompanyId()); + nextOrPreviousFormResponse.setCompanyName(company.getCompanyName()); List flowEdgesList = flowEdgesRepository.findByCallId(applicationEntity.getCall().getId()); Long totalFormSteps = calculateTotalSteps(flowEdgesList); diff --git a/src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java b/src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java index 456a614b..5ec81347 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/PdfDao.java @@ -57,7 +57,7 @@ public class PdfDao { try { UserEntity userEntity = validator.validateUser(request); ApplicationEntity applicationEntity = applicationDao.validateApplication(applicationId); - validator.validateUserWithCompany(request, applicationEntity.getCompany().getId()); + validator.validateUserWithCompany(request, applicationEntity.getCompanyId()); CallEntity call=callService.validateCall(applicationEntity.getCall().getId()); // Create a byte stream to hold the PDF diff --git a/src/main/java/net/gepafin/tendermanagement/entities/ApplicationEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/ApplicationEntity.java index 68c433e2..6e65bf83 100644 --- a/src/main/java/net/gepafin/tendermanagement/entities/ApplicationEntity.java +++ b/src/main/java/net/gepafin/tendermanagement/entities/ApplicationEntity.java @@ -12,10 +12,9 @@ public class ApplicationEntity extends BaseEntity { @Column(name = "USER_ID") private Long userId; - - @ManyToOne - @JoinColumn(name = "COMPANY_ID", nullable = false) - private CompanyEntity company; + + @Column(name = "COMPANY_ID") + private Long companyId; @Column(name = "SUBMISSION_DATE") private LocalDateTime submissionDate; @@ -39,4 +38,8 @@ public class ApplicationEntity extends BaseEntity { @Column(name = "HUB_ID") private Long hubId; + + @ManyToOne + @JoinColumn(name = "USER_WITH_COMPANY_ID") + private UserWithCompanyEntity userWithCompany; } \ No newline at end of file diff --git a/src/main/java/net/gepafin/tendermanagement/entities/BeneficiaryPreferredCallEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/BeneficiaryPreferredCallEntity.java index 7a30c267..5bbc316d 100644 --- a/src/main/java/net/gepafin/tendermanagement/entities/BeneficiaryPreferredCallEntity.java +++ b/src/main/java/net/gepafin/tendermanagement/entities/BeneficiaryPreferredCallEntity.java @@ -34,6 +34,11 @@ public class BeneficiaryPreferredCallEntity extends BaseEntity{ @Column(name = "STATUS", length = 255) private String status; + @Column(name="IS_DELETED") private Boolean isDeleted; + + @ManyToOne + @JoinColumn(name = "USER_WITH_COMPANY_ID") + private UserWithCompanyEntity userWithCompany; } diff --git a/src/main/java/net/gepafin/tendermanagement/entities/FaqEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/FaqEntity.java index a476f2c5..46ebff24 100644 --- a/src/main/java/net/gepafin/tendermanagement/entities/FaqEntity.java +++ b/src/main/java/net/gepafin/tendermanagement/entities/FaqEntity.java @@ -45,5 +45,9 @@ public class FaqEntity extends BaseEntity { @Column(name ="COMPANY_ID") private Long companyId; + @ManyToOne + @JoinColumn(name = "USER_WITH_COMPANY_ID") + private UserWithCompanyEntity userWithCompany; + } diff --git a/src/main/java/net/gepafin/tendermanagement/entities/UserCompanyDelegationEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/UserCompanyDelegationEntity.java index d682747d..9def5dc3 100644 --- a/src/main/java/net/gepafin/tendermanagement/entities/UserCompanyDelegationEntity.java +++ b/src/main/java/net/gepafin/tendermanagement/entities/UserCompanyDelegationEntity.java @@ -1,8 +1,6 @@ package net.gepafin.tendermanagement.entities; -import jakarta.persistence.Column; -import jakarta.persistence.Entity; -import jakarta.persistence.Table; +import jakarta.persistence.*; import lombok.Data; @Data @@ -28,4 +26,7 @@ public class UserCompanyDelegationEntity extends BaseEntity{ @Column(name="STATUS") private String status; + @ManyToOne + @JoinColumn(name = "USER_WITH_COMPANY_ID") + private UserWithCompanyEntity userWithCompany; } diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/BeneficiaryPreferredCallResponseBean.java b/src/main/java/net/gepafin/tendermanagement/model/response/BeneficiaryPreferredCallResponseBean.java index 9588b576..aa07ab69 100644 --- a/src/main/java/net/gepafin/tendermanagement/model/response/BeneficiaryPreferredCallResponseBean.java +++ b/src/main/java/net/gepafin/tendermanagement/model/response/BeneficiaryPreferredCallResponseBean.java @@ -20,6 +20,7 @@ public class BeneficiaryPreferredCallResponseBean { private BeneficiaryCallStatus status; private LocalDateTime createdDate; private LocalDateTime updatedDate; + private Long userWithCompanyId; } diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationRepository.java index 38d73e8d..8877fbc7 100644 --- a/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationRepository.java +++ b/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationRepository.java @@ -24,15 +24,17 @@ public interface ApplicationRepository extends JpaRepository findByIdAndUserIdAndIsDeletedFalse(Long id,Long userId); - Optional findByUserIdAndCompanyIdAndCallIdAndIsDeletedFalse(Long userId, Long companyId, Long callId); + Optional findByUserIdAndUserWithCompanyIdAndCallIdAndIsDeletedFalse(Long userId, Long userWithCompanyId, Long callId); public Optional findByIdAndUserIdAndCallIdAndIsDeletedFalse(Long applicationId, Long userId, Long callId); - @Query("SELECT COUNT(a) FROM ApplicationEntity a WHERE a.userId = :userId AND a.company.id = :companyId AND a.status = 'SUBMIT' AND a.isDeleted = false") - Long countSubmittedApplicationsByUserId(@Param("userId") Long userId, @Param("companyId") Long companyId); + @Query("SELECT COUNT(a) FROM ApplicationEntity a WHERE a.userId = :userId AND a.userWithCompany.id = :userWithCompanyId AND a.status = 'SUBMIT' AND a.isDeleted = false") + Long countSubmittedApplicationsByUserId(@Param("userId") Long userId, @Param("userWithCompanyId") Long userWithCompanyId); + + + List findByUserWithCompanyIdAndUserIdAndIsDeletedFalse(Long userWithCompanyId, Long userId); - List findByCompanyIdAndUserIdAndIsDeletedFalse(Long companyId,Long userId); @Query("SELECT COUNT(a) FROM ApplicationEntity a WHERE a.status = 'SUBMIT' And a.hubId = :hubId AND a.isDeleted = false") public Long countSubmittedApplicationsByHubId(@Param("hubId") Long hubId); diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/BeneficiaryPreferredCallRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/BeneficiaryPreferredCallRepository.java index c83be4d8..6db58fec 100644 --- a/src/main/java/net/gepafin/tendermanagement/repositories/BeneficiaryPreferredCallRepository.java +++ b/src/main/java/net/gepafin/tendermanagement/repositories/BeneficiaryPreferredCallRepository.java @@ -13,12 +13,17 @@ public interface BeneficiaryPreferredCallRepository extends JpaRepository findByBeneficiaryIdAndIsDeletedFalse(Long beneficiaryId); List findByUserIdAndIsDeletedFalse(Long userId); - @Query("SELECT preferredCall FROM BeneficiaryPreferredCallEntity preferredCall where preferredCall.userId=:userId AND (:companyId is null OR preferredCall.companyId=:companyId) AND isDeleted=false") - List findByUserIdAndCompanyIdAndIsDeletedFalse(@Param("userId") Long userId, @Param("companyId") Long companyId); + @Query("SELECT preferredCall FROM BeneficiaryPreferredCallEntity preferredCall WHERE preferredCall.userId = :userId AND (:userWithCompanyId IS NULL OR preferredCall.userWithCompany.id = :userWithCompanyId) AND isDeleted = false") + List findByUserIdAndUserWithCompanyIdAndIsDeletedFalse(@Param("userId") Long userId, @Param("userWithCompanyId") Long userWithCompanyId); + List findByBeneficiaryIdAndCompanyId(Long beneficiaryId,Long companyId); + List findByUserIdAndCallIdInAndIsDeletedFalse(Long userId, List callIds); Optional findByIdAndIsDeletedFalse(Long id); - Optional findByUserIdAndCallIdAndCompanyIdAndIsDeletedFalse(Long userId, Long callId, Long companyId); - List findByUserIdAndCallIdInAndCompanyIdAndIsDeletedFalse(Long userId, List callIds,Long companyId); + + Optional findByUserIdAndCallIdAndUserWithCompanyIdAndIsDeletedFalse(Long userId, Long callId, Long userWithCompanyId); + + List findByUserIdAndCallIdInAndUserWithCompanyIdAndIsDeletedFalse(Long userId, List callIds, Long userWithCompanyId); + } diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/FaqRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/FaqRepository.java index 51642934..a8ada0e1 100644 --- a/src/main/java/net/gepafin/tendermanagement/repositories/FaqRepository.java +++ b/src/main/java/net/gepafin/tendermanagement/repositories/FaqRepository.java @@ -19,6 +19,8 @@ public interface FaqRepository extends JpaRepository { List findByCallIdAndIsDeletedFalse(Long callId); Optional findByIdAndCallIdAndIsDeletedFalse(Long id, Long callId); - List findByCompanyIdAndUserIdAndIsDeletedFalse(Long companyId,Long userId); + + List findByUserWithCompanyIdAndIsDeletedFalse(Long userWithCompanyId); + } diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/UserCompanyDelegationRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/UserCompanyDelegationRepository.java index 03067c80..4cbe8875 100644 --- a/src/main/java/net/gepafin/tendermanagement/repositories/UserCompanyDelegationRepository.java +++ b/src/main/java/net/gepafin/tendermanagement/repositories/UserCompanyDelegationRepository.java @@ -9,7 +9,7 @@ import java.util.List; public interface UserCompanyDelegationRepository extends JpaRepository { - UserCompanyDelegationEntity findByUserIdAndCompanyIdAndStatus(Long userId, Long companyId, String status); + UserCompanyDelegationEntity findByUserIdAndUserWithCompanyIdAndStatus(Long userId, Long userWithCompanyId, String status); @Query("SELECT d FROM UserCompanyDelegationEntity d where d.status = :status") List findAllByStatus(@Param("status") String status); diff --git a/src/main/java/net/gepafin/tendermanagement/service/CompanyService.java b/src/main/java/net/gepafin/tendermanagement/service/CompanyService.java index f11e0798..2896419a 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/CompanyService.java +++ b/src/main/java/net/gepafin/tendermanagement/service/CompanyService.java @@ -31,7 +31,9 @@ public interface CompanyService { CompanyEntity validateCompany(Long companyId); UserWithCompanyEntity validateUserWithCompny(Long userId, Long companyId); - + + UserWithCompanyEntity getUserWithCompany(Long userId, Long companyId); + ByteArrayOutputStream downloadCompanyDelegation(HttpServletRequest request, Long companyId, CompanyDelegationRequest companyDelegationRequest); CompanyDelegationResponse uploadCompanyDelegation(HttpServletRequest request, Long companyId, MultipartFile file); diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationServiceImpl.java index a8d63f1c..80cfd481 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationServiceImpl.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationServiceImpl.java @@ -80,7 +80,7 @@ public class ApplicationServiceImpl implements ApplicationService { public NextOrPreviousFormResponse getNextOrPreviousForm(HttpServletRequest request, Long applicationId, Long formId, FormActionEnum action) { ApplicationEntity applicationEntity = validateApplication(applicationId); - validator.validateUserWithCompany(request, applicationEntity.getCompany().getId()); + validator.validateUserWithCompany(request, applicationEntity.getCompanyId()); return flowFormDao.getNextOrPreviousForm(applicationEntity, formId, action); } diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/CompanyServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/CompanyServiceImpl.java index 5ab99b13..419f8fd6 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/CompanyServiceImpl.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/CompanyServiceImpl.java @@ -90,7 +90,10 @@ public class CompanyServiceImpl implements CompanyService { public UserWithCompanyEntity validateUserWithCompny(Long userId, Long companyId) { return companyDao.validateUserWithCompny(userId, companyId); } - + @Override + public UserWithCompanyEntity getUserWithCompany(Long userId, Long companyId) { + return companyDao.getUserWithCompany(userId, companyId); + } @Override @Transactional(readOnly = true) public ByteArrayOutputStream downloadCompanyDelegation(HttpServletRequest request, Long companyId, CompanyDelegationRequest companyDelegationRequest) { 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 05f8d108..7acc8713 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 @@ -1798,4 +1798,27 @@ role_type = 'ROLE_PRE_INSTRUCTOR' + + + + + + + + + + + + + + + + + + + + + + + From 2ffc924343c8ba724d9c4e786ee6c31dd35a6afa Mon Sep 17 00:00:00 2001 From: rajesh Date: Wed, 27 Nov 2024 12:20:06 +0530 Subject: [PATCH 33/43] Fixed issue with evaluation --- .../dao/ApplicationEvaluationDao.java | 18 ++++++++++++------ .../CallTargetAudienceChecklistRepository.java | 4 ++-- .../EvaluationCriteriaRepository.java | 2 +- .../impl/ApplicationEvaluationServiceImpl.java | 10 ++++------ 4 files changed, 19 insertions(+), 15 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java index 1b725c96..ee5cfe23 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java @@ -111,8 +111,10 @@ public class ApplicationEvaluationDao { populateBasicDetails(entity, response); CallEntity call = callRepository.findCallEntityByApplicationId(entity.getApplicationId()); - List evaluationCriterias = evaluationCriteriaRepository.findByCallId(call.getId()); - List checklistEntities = callTargetAudienceChecklistRepository.findByCallId(call.getId()); + List evaluationCriterias = evaluationCriteriaRepository + .findByCallIdAndLookupDataTypeAndIsDeletedFalse(call.getId(), LookUpDataEntity.LookUpDataTypeEnum.EVALUATION_CRITERIA.getValue()); + List checklistEntities = callTargetAudienceChecklistRepository + .findByCallIdAndLookupDataTypeAndIsDeletedFalse(call.getId(), LookUpDataEntity.LookUpDataTypeEnum.CHECKLIST.getValue()); List applicationFormEntities = applicationFormRepository.findByApplicationId(entity.getApplicationId()); setCriteriaResponses(entity, response, evaluationCriterias); @@ -633,8 +635,10 @@ public class ApplicationEvaluationDao { call = callRepository.findCallEntityByApplicationId(applicationId); assignedApplications = assignedApplicationsRepository.findByApplicationIdAndIsDeletedFalse(applicationId).orElse(null); } - List evaluationCriterias = evaluationCriteriaRepository.findByCallId(call.getId()); - List checklistEntities = callTargetAudienceChecklistRepository.findByCallId(call.getId()); + List evaluationCriterias = evaluationCriteriaRepository + .findByCallIdAndLookupDataTypeAndIsDeletedFalse(call.getId(), LookUpDataEntity.LookUpDataTypeEnum.EVALUATION_CRITERIA.getValue()); + List checklistEntities = callTargetAudienceChecklistRepository + .findByCallIdAndLookupDataTypeAndIsDeletedFalse(call.getId(), LookUpDataEntity.LookUpDataTypeEnum.CHECKLIST.getValue()); List applicationFormEntities = applicationFormRepository.findByApplicationId(applicationId); response.setApplicationId(application.getId()); response.setAssignedApplicationId(assignedApplications.getId()); @@ -966,7 +970,8 @@ public class ApplicationEvaluationDao { } private List getEvaluationCriterias(CallEntity call) { - return evaluationCriteriaRepository.findByCallId(call.getId()); + return evaluationCriteriaRepository + .findByCallIdAndLookupDataTypeAndIsDeletedFalse(call.getId(), LookUpDataEntity.LookUpDataTypeEnum.EVALUATION_CRITERIA.getValue()); } private CriteriaResponse buildCriteriaResponse(Long applicationId, EvaluationCriteriaEntity criteria) { @@ -1207,7 +1212,8 @@ public class ApplicationEvaluationDao { List getChecklistResponse(Long applicationId) { CallEntity call = callRepository.findCallEntityByApplicationId(applicationId); - List checklistEntities = callTargetAudienceChecklistRepository.findByCallId(call.getId()); + List checklistEntities = callTargetAudienceChecklistRepository + .findByCallIdAndLookupDataTypeAndIsDeletedFalse(call.getId(), LookUpDataEntity.LookUpDataTypeEnum.CHECKLIST.getValue()); List checklistResponses = checklistEntities.stream().map(checklist -> { ChecklistResponse response = new ChecklistResponse(); response.setId(checklist.getId()); diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/CallTargetAudienceChecklistRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/CallTargetAudienceChecklistRepository.java index d092ea4a..95f58f8a 100644 --- a/src/main/java/net/gepafin/tendermanagement/repositories/CallTargetAudienceChecklistRepository.java +++ b/src/main/java/net/gepafin/tendermanagement/repositories/CallTargetAudienceChecklistRepository.java @@ -12,10 +12,10 @@ import net.gepafin.tendermanagement.entities.CallTargetAudienceChecklistEntity; @Repository public interface CallTargetAudienceChecklistRepository extends JpaRepository { - + @Query("SELECT c FROM CallTargetAudienceChecklistEntity c WHERE c.id = :id AND c.isDeleted = false") Optional findById(@Param("id") Long id); List findByCallIdAndLookupDataTypeAndIsDeletedFalse(Long id, String type); - List findByCallId(Long callId); +// List findByCallId(Long callId); } diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/EvaluationCriteriaRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/EvaluationCriteriaRepository.java index 8b25fc1f..1a7f7ccd 100644 --- a/src/main/java/net/gepafin/tendermanagement/repositories/EvaluationCriteriaRepository.java +++ b/src/main/java/net/gepafin/tendermanagement/repositories/EvaluationCriteriaRepository.java @@ -16,6 +16,6 @@ public interface EvaluationCriteriaRepository extends JpaRepository findById(@Param("id") Long id); List findByCallIdAndLookupDataTypeAndIsDeletedFalse(Long callId, String type); - List findByCallId(Long callId); +// List findByCallId(Long callId); } diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationEvaluationServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationEvaluationServiceImpl.java index 6ccee608..30cdaf80 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationEvaluationServiceImpl.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationEvaluationServiceImpl.java @@ -14,6 +14,7 @@ import net.gepafin.tendermanagement.model.response.ApplicationEvaluationResponse import net.gepafin.tendermanagement.repositories.AssignedApplicationsRepository; import net.gepafin.tendermanagement.service.ApplicationEvaluationService; +import net.gepafin.tendermanagement.service.AssignedApplicationsService; import net.gepafin.tendermanagement.util.Validator; import net.gepafin.tendermanagement.web.rest.api.errors.CustomValidationException; import net.gepafin.tendermanagement.web.rest.api.errors.ResourceNotFoundException; @@ -32,8 +33,9 @@ public class ApplicationEvaluationServiceImpl implements ApplicationEvaluationSe @Autowired private Validator validator; @Autowired + private AssignedApplicationsService assignedApplicationsService; + @Autowired private AssignedApplicationsRepository assignedApplicationsRepository; - @Override @Transactional(rollbackFor = Exception.class) public ApplicationEvaluationResponse createOrUpdateApplicationEvaluation( @@ -41,11 +43,7 @@ public class ApplicationEvaluationServiceImpl implements ApplicationEvaluationSe ApplicationEvaluationRequest req, Long assignedApplicationsId) { - AssignedApplicationsEntity assignedApplication = assignedApplicationsRepository - .findByIdAndIsDeletedFalse(assignedApplicationsId) - .orElseThrow(() -> new ResourceNotFoundException( - Status.NOT_FOUND, - Translator.toLocale(GepafinConstant.ASSIGNED_APPLICATION_NOT_FOUND_MSG))); + AssignedApplicationsEntity assignedApplication =assignedApplicationsService.validateAssignedApplication(assignedApplicationsId); UserEntity user = validator.validatePreInstructor(request, assignedApplication.getUserId()); From d21445be38fafe4a5ef1371dc67928ea88075911 Mon Sep 17 00:00:00 2001 From: nishainnogent Date: Thu, 28 Nov 2024 12:17:31 +0530 Subject: [PATCH 34/43] Amendment Documents --- .../tendermanagement/dao/ApplicationDao.java | 6 +- .../gepafin/tendermanagement/dao/CallDao.java | 2 +- .../tendermanagement/dao/DelegationDao.java | 2 +- .../tendermanagement/dao/DocumentDao.java | 59 ++++++++++++++----- .../tendermanagement/dao/S3PathConfig.java | 19 +++--- .../enums/DocOtherSourceTypeEnum.java | 3 +- .../enums/DocumentSourceTypeEnum.java | 4 +- ...ApplicationAmendmentRequestRepository.java | 9 +++ .../service/AmazonS3Service.java | 5 +- .../service/impl/AmazonS3ServiceImpl.java | 10 ++-- .../impl/S3ReUploadMigrationService.java | 4 +- .../UserSignedAndDelegationServiceImpl.java | 2 +- .../db/changelog/db.changelog-1.0.0.xml | 48 +++++++++++++++ 13 files changed, 132 insertions(+), 41 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java index 017870ed..1f90b544 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java @@ -983,7 +983,7 @@ public class ApplicationDao { } private String generateS3PathForDelegation(Long callId, Long applicationId) { try { - return s3ConfigBean.generateDocumentPathForOther(DocOtherSourceTypeEnum.USER_SIGNED_DOCUMENT, callId, applicationId); + return s3ConfigBean.generateDocumentPathForOther(DocOtherSourceTypeEnum.USER_SIGNED_DOCUMENT, callId, applicationId,0L); } catch (IllegalArgumentException e) { throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.S3_PATH_GENERATION_ERROR_MSG)); } @@ -1125,7 +1125,7 @@ public class ApplicationDao { try (ByteArrayOutputStream zipOutputStream = new ByteArrayOutputStream(); ZipOutputStream zos = new ZipOutputStream(zipOutputStream)) { - String s3Folder = s3PathConfig.generateDocumentPath(DocumentSourceTypeEnum.APPLICATION, applicationEntity.getCall().getId(), applicationId); + String s3Folder = s3PathConfig.generateDocumentPath(DocumentSourceTypeEnum.APPLICATION, applicationEntity.getCall().getId(), applicationId,0L); for (DocumentEntity document : documents) { String fileName = Utils.extractFileName(document.getFilePath()); @@ -1133,7 +1133,7 @@ public class ApplicationDao { } if (signedDocument != null) { - String signedDocS3Folder = s3PathConfig.generateDocumentPathForOther(DocOtherSourceTypeEnum.USER_SIGNED_DOCUMENT, applicationEntity.getCall().getId(), applicationId); + String signedDocS3Folder = s3PathConfig.generateDocumentPathForOther(DocOtherSourceTypeEnum.USER_SIGNED_DOCUMENT, applicationEntity.getCall().getId(), applicationId,0L); String signedDocFileName = signedDocument.getFileName(); addDocumentToZip(zos, signedDocS3Folder, signedDocument.getFilePath(), signedDocFileName); } diff --git a/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java b/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java index b19a50d2..ce5d8c28 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java @@ -120,7 +120,7 @@ public class CallDao { ZipOutputStream zos = new ZipOutputStream(zipOutputStream)) { for (DocumentEntity document : documents) { - String s3Folder = s3PathConfig.generateDocumentPath(DocumentSourceTypeEnum.CALL, callId, 0L); + String s3Folder = s3PathConfig.generateDocumentPath(DocumentSourceTypeEnum.CALL, callId, 0L,0L); try (InputStream fileInputStream = amazonS3Service.getFile(s3Folder, document.getFilePath())) { String fileName = Utils.extractFileName(document.getFilePath()); ZipEntry zipEntry = new ZipEntry(fileName); diff --git a/src/main/java/net/gepafin/tendermanagement/dao/DelegationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/DelegationDao.java index 3fd9d83f..407a8aff 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/DelegationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/DelegationDao.java @@ -69,7 +69,7 @@ public class DelegationDao { public ByteArrayOutputStream generateDocument(Map placeholders, String templateName) { try { - String s3Folder = s3ConfigBean.generateDocumentPathForOther(DocOtherSourceTypeEnum.TEMPLATE, 0L, 0L); + String s3Folder = s3ConfigBean.generateDocumentPathForOther(DocOtherSourceTypeEnum.TEMPLATE, 0L, 0L,0L); InputStream templateStream = amazonS3Service.getFile(s3Folder ,templateName); XWPFDocument doc = loadTemplate(templateStream); replacePlaceholders(doc, placeholders); diff --git a/src/main/java/net/gepafin/tendermanagement/dao/DocumentDao.java b/src/main/java/net/gepafin/tendermanagement/dao/DocumentDao.java index c2339d5d..c4cab6b2 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/DocumentDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/DocumentDao.java @@ -9,9 +9,11 @@ import net.gepafin.tendermanagement.enums.DocumentSourceTypeEnum; import net.gepafin.tendermanagement.enums.DocumentTypeEnum; import net.gepafin.tendermanagement.model.response.DocumentResponseBean; import net.gepafin.tendermanagement.model.response.UploadFileOnAmazonS3Response; +import net.gepafin.tendermanagement.repositories.ApplicationAmendmentRequestRepository; import net.gepafin.tendermanagement.repositories.ApplicationRepository; import net.gepafin.tendermanagement.repositories.DocumentRepository; import net.gepafin.tendermanagement.service.AmazonS3Service; +import net.gepafin.tendermanagement.service.ApplicationAmendmentRequestService; import net.gepafin.tendermanagement.service.ApplicationService; import net.gepafin.tendermanagement.service.CallService; import net.gepafin.tendermanagement.web.rest.api.errors.CustomValidationException; @@ -50,11 +52,16 @@ public class DocumentDao { @Autowired ApplicationService applicationService; + @Autowired + ApplicationAmendmentRequestService applicationAmendmentRequestService; + + @Autowired + ApplicationAmendmentRequestRepository applicationAmendmentRequestRepository; + @Value("${aws.s3.bucket.name}") private String bucketName; - // @Value("${aws.s3.url.folder}") // private String s3Folder; @@ -77,30 +84,38 @@ public class DocumentDao { documentRepository.saveAll(documentEntities); return documentEntities.stream().map(callDao::convertToDocumentResponseBean).collect(Collectors.toList()); } + private UploadFileOnAmazonS3Response uploadFileOnAmazonS3(MultipartFile file, DocumentSourceTypeEnum type, Long sourceId) { - Long applicationId = 0L; + Long applicationId = 0L; + Long amendmentId = 0L; Long callId = sourceId; if (type == DocumentSourceTypeEnum.APPLICATION) { applicationId = sourceId; callId = applicationFormRepository.findCallIdById(applicationId); + } else if (type == DocumentSourceTypeEnum.AMENDMENT) { + amendmentId = sourceId; + ApplicationEntity applicationEntity = applicationAmendmentRequestRepository.findApplicationByAmendmentId(amendmentId); + applicationId = applicationEntity.getId(); + callId = applicationEntity.getCall().getId(); } try { - String s3Path = generateS3Path(type, callId, applicationId); + String s3Path = generateS3Path(type, callId, applicationId, amendmentId); log.info("Generated S3 path {}", s3Path); return amazonS3Service.uploadFileOnAmazonS3(s3Path, file); } catch (Exception e) { throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.UPLOAD_ERROR_S3)); } } - public String generateS3Path(DocumentSourceTypeEnum typeOfDocument, Long callId, Long applicationId) { + public String generateS3Path(DocumentSourceTypeEnum typeOfDocument, Long callId, Long applicationId, Long amendmentId) { try { - return s3ConfigBean.generateDocumentPath(typeOfDocument, callId, applicationId); + return s3ConfigBean.generateDocumentPath(typeOfDocument, callId, applicationId, amendmentId); } catch (IllegalArgumentException e) { throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.S3_PATH_GENERATION_ERROR_MSG)); } } + private Long resolveSourceId(Long sourceId, DocumentSourceTypeEnum sourceType) { if (sourceType == DocumentSourceTypeEnum.CALL) { CallEntity callEntity = callService.validateCall(sourceId); @@ -119,16 +134,23 @@ public class DocumentDao { DocumentEntity documentEntity = validateDocument(documentId); Long callId = null; Long applicationId = null; + Long amendmentId = null; - if ("CALL".equalsIgnoreCase(documentEntity.getSource())) { + if (DocumentSourceTypeEnum.CALL.getValue().equalsIgnoreCase(documentEntity.getSource())) { callId = documentEntity.getSourceId(); - } else if ("APPLICATION".equalsIgnoreCase(documentEntity.getSource())) { + } else if (DocumentSourceTypeEnum.APPLICATION.getValue().equalsIgnoreCase(documentEntity.getSource())) { applicationId = documentEntity.getSourceId(); ApplicationEntity applicationEntity = applicationService.validateApplication(applicationId); callId = applicationEntity.getCall().getId(); } + else if(DocumentSourceTypeEnum.AMENDMENT.getValue().equalsIgnoreCase(documentEntity.getSource())){ + amendmentId = documentEntity.getSourceId(); + ApplicationEntity applicationEntity = applicationAmendmentRequestRepository.findApplicationByAmendmentId(amendmentId); + applicationId = applicationEntity.getId(); + callId = applicationEntity.getCall().getId(); + } - amazonS3Service.deleteFileFromS3(documentEntity,callId,applicationId); + amazonS3Service.deleteFileFromS3(documentEntity, callId, applicationId,amendmentId); documentEntity.setIsDeleted(true); documentRepository.save(documentEntity); } @@ -142,7 +164,7 @@ public class DocumentDao { DocumentEntity documentEntity = validateDocument(documentId); String type = documentEntity.getSource(); UploadFileOnAmazonS3Response uploadFileOnAmazonS3Response = updateFileOnAmazonS3(file, DocumentSourceTypeEnum.valueOf(type), documentEntity.getSourceId()); - if (uploadFileOnAmazonS3Response != null) { + if (uploadFileOnAmazonS3Response != null) { documentEntity.setFileName(uploadFileOnAmazonS3Response.getFileName()); documentEntity.setFilePath(uploadFileOnAmazonS3Response.getFilePath()); documentEntity.setType(documentTypeEnum.getValue()); @@ -152,19 +174,28 @@ public class DocumentDao { } return callDao.convertToDocumentResponseBean(documentEntity); } + private UploadFileOnAmazonS3Response updateFileOnAmazonS3(MultipartFile file, DocumentSourceTypeEnum type, Long id) { try { - Long callId; - Long applicationId; - if(type.equals(DocumentSourceTypeEnum.APPLICATION)){ + Long callId=null; + Long applicationId=null; + Long amendmentId=null; + if (type.equals(DocumentSourceTypeEnum.APPLICATION)) { callId = applicationFormRepository.findCallIdById(id); applicationId = id; - }else{ + } + else if(type.equals(DocumentSourceTypeEnum.AMENDMENT)){ + amendmentId = id; + ApplicationEntity applicationEntity = applicationAmendmentRequestRepository.findApplicationByAmendmentId(amendmentId); + applicationId = applicationEntity.getId(); + callId = applicationEntity.getCall().getId(); + } + else { callId = id; applicationId = 0L; } - String s3Path = generateS3Path(type, callId, applicationId); + String s3Path = generateS3Path(type, callId, applicationId,amendmentId); log.info("Generated S3 path {}", s3Path); return amazonS3Service.uploadFileOnAmazonS3(s3Path, file); } catch (Exception e) { diff --git a/src/main/java/net/gepafin/tendermanagement/dao/S3PathConfig.java b/src/main/java/net/gepafin/tendermanagement/dao/S3PathConfig.java index b127b699..1db01f11 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/S3PathConfig.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/S3PathConfig.java @@ -13,25 +13,28 @@ public class S3PathConfig { @Autowired S3ConfigRepository s3ConfigRepository; - public String generateDocumentPath(DocumentSourceTypeEnum type, Long callId, Long applicationId) { + public String generateDocumentPath(DocumentSourceTypeEnum type, Long callId, Long applicationId,Long amendmentId) { S3ConfigEntity config = getDocumentPath(type); - return config.getParentFolder() + "/" + buildS3Path(config.getPath(), callId, applicationId); + return config.getParentFolder() + "/" + buildS3Path(config.getPath(), callId, applicationId,amendmentId); } - public String generateDocumentPathForOther(DocOtherSourceTypeEnum type, Long callId, Long applicationId) { + public String generateDocumentPathForOther(DocOtherSourceTypeEnum type, Long callId, Long applicationId,Long amendmentId) { S3ConfigEntity config = getDocumentPathForOther(type); - return config.getParentFolder() + "/" + buildS3Path(config.getPath(), callId, applicationId); - } - private String buildS3Path(String pathTemplate, Long callId, Long applicationId) { - - return pathTemplate.replace("{call_id}", callId != null && callId != 0L ? "call_" + callId : "").replace("{application_id}", applicationId != null && applicationId != 0L ? "application_" + applicationId : ""); + return config.getParentFolder() + "/" + buildS3Path(config.getPath(), callId, applicationId,amendmentId); } public String generateDocumentPathForDelegationAndSignedDocument(DocOtherSourceTypeEnum type) { S3ConfigEntity config = getDocumentPathForOther(type); return config.getParentFolder() + "/" + config.getPath(); } + private String buildS3Path(String pathTemplate, Long callId, Long applicationId, Long amendmentId) { + return pathTemplate + .replace("{call_id}", callId != null && callId != 0L ? "call_" + callId : "") + .replace("{application_id}", applicationId != null && applicationId != 0L ? "application_" + applicationId : "") + .replace("{amendment_id}", amendmentId != null && amendmentId != 0L ? "amendment_" + amendmentId : ""); + } + private S3ConfigEntity getDocumentPath(DocumentSourceTypeEnum type) { return s3ConfigRepository.getPathByType(type.name()).orElseThrow(() -> new IllegalArgumentException("No path configuration found for type: " + type)); diff --git a/src/main/java/net/gepafin/tendermanagement/enums/DocOtherSourceTypeEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/DocOtherSourceTypeEnum.java index 998c7d13..556a9949 100644 --- a/src/main/java/net/gepafin/tendermanagement/enums/DocOtherSourceTypeEnum.java +++ b/src/main/java/net/gepafin/tendermanagement/enums/DocOtherSourceTypeEnum.java @@ -6,7 +6,8 @@ public enum DocOtherSourceTypeEnum { TEMPLATE("TEMPLATE"), DELETED_USER_DELEGATION("DELETED_USER_DELEGATION"), DELETED_APPLICATION("DELETED_APPLICATION"), - DELETED_CALL("DELETED_CALL"); + DELETED_CALL("DELETED_CALL"), + DELETED_AMENDMENT("DELETED_AMENDMENT"); private String value; diff --git a/src/main/java/net/gepafin/tendermanagement/enums/DocumentSourceTypeEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/DocumentSourceTypeEnum.java index 123c6f8c..7ac28ac7 100644 --- a/src/main/java/net/gepafin/tendermanagement/enums/DocumentSourceTypeEnum.java +++ b/src/main/java/net/gepafin/tendermanagement/enums/DocumentSourceTypeEnum.java @@ -3,7 +3,9 @@ package net.gepafin.tendermanagement.enums; public enum DocumentSourceTypeEnum { CALL("CALL"), - APPLICATION("APPLICATION"); + APPLICATION("APPLICATION"), + + AMENDMENT("AMENDMENT"); private String value; diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationAmendmentRequestRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationAmendmentRequestRepository.java index 57331e43..9773f3ed 100644 --- a/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationAmendmentRequestRepository.java +++ b/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationAmendmentRequestRepository.java @@ -1,6 +1,7 @@ package net.gepafin.tendermanagement.repositories; import net.gepafin.tendermanagement.entities.ApplicationAmendmentRequestEntity; +import net.gepafin.tendermanagement.entities.ApplicationEntity; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.jpa.repository.Query; @@ -34,4 +35,12 @@ public interface ApplicationAmendmentRequestRepository extends JpaRepository findByApplicationIdAndStatusInAndIsDeletedFalse(Long applicationId, List statuses); + @Query("SELECT app " + + "FROM ApplicationEntity app " + + "WHERE app.id = (SELECT aar.applicationId " + + "FROM ApplicationAmendmentRequestEntity aar " + + "WHERE aar.id = :amendmentId)") + ApplicationEntity findApplicationByAmendmentId(Long amendmentId); + + } diff --git a/src/main/java/net/gepafin/tendermanagement/service/AmazonS3Service.java b/src/main/java/net/gepafin/tendermanagement/service/AmazonS3Service.java index 92cbdfab..c9de1287 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/AmazonS3Service.java +++ b/src/main/java/net/gepafin/tendermanagement/service/AmazonS3Service.java @@ -1,5 +1,4 @@ package net.gepafin.tendermanagement.service; - import net.gepafin.tendermanagement.entities.DocumentEntity; import net.gepafin.tendermanagement.entities.UserCompanyDelegationEntity; import net.gepafin.tendermanagement.enums.DocOtherSourceTypeEnum; @@ -21,7 +20,7 @@ AmazonS3Service { InputStream getFile(String s3Folder, String filePath) throws IOException; - String generateS3PathForDeletedDocument(DocOtherSourceTypeEnum typeOfDocument, Long callId, Long applicationId); + String generateS3PathForDeletedDocument(DocOtherSourceTypeEnum typeOfDocument, Long callId, Long applicationId,Long amendmentId); String generateS3PathForDeletedDocumentForOther(); @@ -29,6 +28,6 @@ AmazonS3Service { void deleteDelegationfromS3(UserCompanyDelegationEntity userCompanyDelegationEntity); - void deleteFileFromS3(DocumentEntity documentEntity, Long callId, Long applicationId); + void deleteFileFromS3(DocumentEntity documentEntity, Long callId, Long applicationId,Long amendmentId); } \ No newline at end of file diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/AmazonS3ServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/AmazonS3ServiceImpl.java index 5e7624ac..5c251f19 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/AmazonS3ServiceImpl.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/AmazonS3ServiceImpl.java @@ -146,9 +146,9 @@ public class AmazonS3ServiceImpl implements AmazonS3Service { } @Override - public String generateS3PathForDeletedDocument(DocOtherSourceTypeEnum typeOfDocument, Long callId, Long applicationId) { + public String generateS3PathForDeletedDocument(DocOtherSourceTypeEnum typeOfDocument, Long callId, Long applicationId,Long amendmentId) { try { - return s3ConfigBean.generateDocumentPathForOther(typeOfDocument, callId, applicationId); + return s3ConfigBean.generateDocumentPathForOther(typeOfDocument, callId, applicationId,amendmentId); } catch (IllegalArgumentException e) { throw new CustomValidationException( Status.VALIDATION_ERROR, @@ -207,10 +207,10 @@ public class AmazonS3ServiceImpl implements AmazonS3Service { } @Override - public void deleteFileFromS3(DocumentEntity documentEntity, Long callId, Long applicationId) { + public void deleteFileFromS3(DocumentEntity documentEntity, Long callId, Long applicationId,Long amendmentId) { try { String oldS3Path = documentEntity.getFilePath(); - String newS3Path = generateS3PathForDeletedDocument(DocOtherSourceTypeEnum.valueOf("DELETED_" + documentEntity.getSource().toUpperCase()), callId, applicationId) + String newS3Path = generateS3PathForDeletedDocument(DocOtherSourceTypeEnum.valueOf("DELETED_" + documentEntity.getSource().toUpperCase()), callId, applicationId,amendmentId) + "/" + oldS3Path.substring(oldS3Path.lastIndexOf("/") + 1); String bucketUrlPrefix = getBucketUrlPrefix(); if (oldS3Path.startsWith(bucketUrlPrefix)) { @@ -224,6 +224,4 @@ public class AmazonS3ServiceImpl implements AmazonS3Service { throw new CustomValidationException(Status.VALIDATION_ERROR, "Error occurred while moving file to deleted folder."); } } - - } \ No newline at end of file diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/S3ReUploadMigrationService.java b/src/main/java/net/gepafin/tendermanagement/service/impl/S3ReUploadMigrationService.java index 4bc59150..eefe4706 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/S3ReUploadMigrationService.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/S3ReUploadMigrationService.java @@ -164,10 +164,10 @@ public class S3ReUploadMigrationService { Long callId; if (sourceType.equals(DocumentSourceTypeEnum.CALL)) { - return s3ConfigBean.generateDocumentPath(sourceType, document.getSourceId(), 0L); + return s3ConfigBean.generateDocumentPath(sourceType, document.getSourceId(), 0L,0L); } else { callId = applicationRepository.findCallIdById(document.getSourceId()); - return s3ConfigBean.generateDocumentPath(sourceType, callId, document.getSourceId()); + return s3ConfigBean.generateDocumentPath(sourceType, callId, document.getSourceId(),0L); } } diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/UserSignedAndDelegationServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/UserSignedAndDelegationServiceImpl.java index dbd54afd..d66f9aaa 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/UserSignedAndDelegationServiceImpl.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/UserSignedAndDelegationServiceImpl.java @@ -130,7 +130,7 @@ public class UserSignedAndDelegationServiceImpl { private String generateNewS3PathForDelegationDoc() { - return s3ConfigBean.generateDocumentPathForOther(DocOtherSourceTypeEnum.USER_DELEGATION, 0L, 0L); + return s3ConfigBean.generateDocumentPathForOther(DocOtherSourceTypeEnum.USER_DELEGATION, 0L, 0L,0L); } private String generateNewS3PathForUserSignedDoc(ApplicationSignedDocumentEntity document) { 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 ea473da2..3c41c899 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 @@ -1803,4 +1803,52 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 51998245d6724c7083e10fd1b1912d488cda188d Mon Sep 17 00:00:00 2001 From: harish Date: Thu, 28 Nov 2024 12:37:12 +0530 Subject: [PATCH 35/43] updated code for Amendment scheduler --- pom.xml | 5 + .../dao/ApplicationAmendmentRequestDao.java | 7 +- .../enums/UserActionContextEnum.java | 6 +- .../enums/UserActionLogsEnum.java | 3 +- ...ApplicationAmendmentRequestRepository.java | 21 ++- .../ApplicationAmendmentScheduler.java | 122 ++++++++++++++++++ .../ApplicationEvaluationScheduler.java | 89 ++++++++++--- .../scheduler/NotificationScheduler.java | 76 ----------- ...pplicationAmendmentRequestServiceImpl.java | 7 + .../tendermanagement/util/LoggingUtil.java | 9 +- .../gepafin/tendermanagement/util/Utils.java | 16 +++ 11 files changed, 256 insertions(+), 105 deletions(-) create mode 100644 src/main/java/net/gepafin/tendermanagement/scheduler/ApplicationAmendmentScheduler.java delete mode 100644 src/main/java/net/gepafin/tendermanagement/scheduler/NotificationScheduler.java diff --git a/pom.xml b/pom.xml index 08c677d0..f3424e44 100644 --- a/pom.xml +++ b/pom.xml @@ -225,6 +225,11 @@ 3.0.0 + + + org.springframework + spring-test + diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java index 2cf079bf..c9c19708 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java @@ -212,7 +212,7 @@ public class ApplicationAmendmentRequestDao { ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity = new ApplicationAmendmentRequestEntity(); applicationAmendmentRequestEntity.setNote(applicationAmendmentRequest.getNote()); applicationAmendmentRequestEntity.setResponseDays(applicationAmendmentRequest.getResponseDays()); - if(applicationAmendmentRequest.getResponseDays()==null && applicationAmendmentRequest.getResponseDays() < 0){ + if(applicationAmendmentRequest.getResponseDays()==null || applicationAmendmentRequest.getResponseDays() < 0){ throw new CustomValidationException(Status.BAD_REQUEST,Translator.toLocale(GepafinConstant.RESPONSE_DAYS_NOT_NULL)); } applicationAmendmentRequestEntity.setEndDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now()).plusDays(applicationAmendmentRequest.getResponseDays())); @@ -897,7 +897,7 @@ public class ApplicationAmendmentRequestDao { ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity = validateApplicationAmendmentRequest(id); if (newResponseDays != null && newResponseDays > 0) { -ApplicationAmendmentRequestEntity oldApplicationAmendmentEntity = Utils.getClonedEntityForData(applicationAmendmentRequestEntity); + ApplicationAmendmentRequestEntity oldApplicationAmendmentEntity = Utils.getClonedEntityForData(applicationAmendmentRequestEntity); Long currentResponseDays = applicationAmendmentRequestEntity.getResponseDays() != null ? applicationAmendmentRequestEntity.getResponseDays() : 0L; applicationAmendmentRequestEntity.setResponseDays(currentResponseDays + newResponseDays); applicationAmendmentRequestEntity.setEndDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now().plusDays(applicationAmendmentRequestEntity.getResponseDays()))); @@ -1014,6 +1014,9 @@ ApplicationAmendmentRequestEntity oldApplicationAmendmentEntity = Utils.getClone ApplicationEvaluationEntity oldApplicationEvaluationEntity = Utils.getClonedEntityForData(applicationEvaluationEntity); applicationEvaluationEntity.setEndDate(endDate); + if(applicationEvaluationEntity.getSuspendedDays() == null) { + applicationEvaluationEntity.setSuspendedDays(0L); + } applicationEvaluationEntity.setSuspendedDays(applicationEvaluationEntity.getSuspendedDays()+suspendedDays); ApplicationEvaluationEntity applicationEvaluation = applicationEvaluationRepository.save(applicationEvaluationEntity); diff --git a/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java index 0a92143b..7023b40b 100644 --- a/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java +++ b/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java @@ -147,7 +147,11 @@ public enum UserActionContextEnum { GET_FORM("GET_FORM"), CREATE_FORM("CREATE_FORM"), UPDATE_FORM("UPDATE_FORM"), - DELETE_FORM("DELETE_FORM"); + DELETE_FORM("DELETE_FORM"), + + /** scheduler action context **/ + AMENDMENT_EXPIRATION_SCHEDULER("AMENDMENT_EXPIRATION_SCHEDULER"), + EVALUATION_EXPIRATION_SCHEDULER("EVALUATION_EXPIRATION_SCHEDULER"); private final String value; diff --git a/src/main/java/net/gepafin/tendermanagement/enums/UserActionLogsEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/UserActionLogsEnum.java index f68f6ae9..6fdd86f5 100644 --- a/src/main/java/net/gepafin/tendermanagement/enums/UserActionLogsEnum.java +++ b/src/main/java/net/gepafin/tendermanagement/enums/UserActionLogsEnum.java @@ -10,7 +10,8 @@ public enum UserActionLogsEnum { VIEW("VIEW"), INSERT("INSERT"), DOWNLOAD("DOWNLOAD"), - UPLOAD("UPLOAD"); + UPLOAD("UPLOAD"), + SCHEDULER("SCHEDULER"); private final String value; diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationAmendmentRequestRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationAmendmentRequestRepository.java index af46d7b5..a5443dd3 100644 --- a/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationAmendmentRequestRepository.java +++ b/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationAmendmentRequestRepository.java @@ -1,6 +1,8 @@ package net.gepafin.tendermanagement.repositories; import net.gepafin.tendermanagement.entities.ApplicationAmendmentRequestEntity; +import net.gepafin.tendermanagement.entities.ApplicationEvaluationEntity; + import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.jpa.repository.Query; @@ -9,6 +11,7 @@ import org.springframework.data.repository.query.Param; import java.time.LocalDateTime; import java.util.List; import java.util.Optional; +import java.util.Set; public interface ApplicationAmendmentRequestRepository extends JpaRepository, JpaSpecificationExecutor { Optional findByIdAndIsDeletedFalse(Long id); @@ -45,10 +48,22 @@ public interface ApplicationAmendmentRequestRepository extends JpaRepository findAllByApplicationEvaluationIdAndStatusAndIsDeletedFalse(Long id, String status); @Query("SELECT a FROM ApplicationAmendmentRequestEntity a " + - "WHERE a.applicationId = :applicationId " + - "AND a.isDeleted = false " + + "WHERE a.isDeleted = false " + "AND a.status <> 'CLOSE' " + "AND a.endDate < :currentTime") - List findActiveAmendments(Long applicationId, LocalDateTime currentTime); + List findAmendmentsDueForExpiration(LocalDateTime currentTime); + + + + @Query("SELECT DISTINCT a.applicationEvaluationEntity " + + "FROM ApplicationAmendmentRequestEntity a " + + "WHERE a.applicationEvaluationEntity.id IN :applicationEvaluationIds " + + "AND a.isDeleted = false " + + "AND NOT EXISTS ( " + + " SELECT 1 FROM ApplicationAmendmentRequestEntity activeAmendment" + + " WHERE activeAmendment.applicationEvaluationEntity.id = a.applicationEvaluationEntity.id " + + " AND activeAmendment.status <> 'CLOSE' " + + " AND activeAmendment.isDeleted = false) ") + Set findEvaluationsWithoutActiveAmendmentsByIds(@Param("applicationEvaluationIds") Set applicationEvaluationIds); } diff --git a/src/main/java/net/gepafin/tendermanagement/scheduler/ApplicationAmendmentScheduler.java b/src/main/java/net/gepafin/tendermanagement/scheduler/ApplicationAmendmentScheduler.java new file mode 100644 index 00000000..a3112a1c --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/scheduler/ApplicationAmendmentScheduler.java @@ -0,0 +1,122 @@ +package net.gepafin.tendermanagement.scheduler; + +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import jakarta.servlet.http.HttpServletRequest; +import net.gepafin.tendermanagement.dao.ApplicationAmendmentRequestDao; +import net.gepafin.tendermanagement.dao.EmailNotificationDao; +import net.gepafin.tendermanagement.entities.ApplicationAmendmentRequestEntity; +import net.gepafin.tendermanagement.entities.ApplicationEvaluationEntity; +import net.gepafin.tendermanagement.enums.ApplicationAmendmentRequestEnum; +import net.gepafin.tendermanagement.enums.UserActionContextEnum; +import net.gepafin.tendermanagement.enums.UserActionLogsEnum; +import net.gepafin.tendermanagement.enums.VersionActionTypeEnum; +import net.gepafin.tendermanagement.model.request.UserActionRequest; +import net.gepafin.tendermanagement.model.request.VersionHistoryRequest; +import net.gepafin.tendermanagement.repositories.ApplicationAmendmentRequestRepository; +import net.gepafin.tendermanagement.util.DateTimeUtil; +import net.gepafin.tendermanagement.util.LoggingUtil; +import net.gepafin.tendermanagement.util.Utils; + +@Component +public class ApplicationAmendmentScheduler { + + @Autowired + private HttpServletRequest httpServletRequest; + + @Autowired + private ApplicationAmendmentRequestRepository applicationAmendmentRepository; + + @Autowired + private EmailNotificationDao emailNotificationDao; + + @Autowired + private ApplicationAmendmentRequestDao applicationAmendmentRequestDao; + + @Autowired + private LoggingUtil loggingUtil; + + private static final Logger log = LoggerFactory.getLogger(ApplicationAmendmentScheduler.class); + + @Scheduled(cron = "0 0 1 * * ?") + public void processAmendmentExpirationScheduler() { + log.info("Starting the Application Amendment Expiration scheduler."); + try { + + Utils.setHttpServletRequestForScheduler(); + + /** This code is responsible for creating user action logs for the "Application Amendment Expiration scheduler" operation. **/ + loggingUtil.logUserActionWithoutToken( + UserActionRequest.builder().request(httpServletRequest).actionType(UserActionLogsEnum.SCHEDULER).actionContext(UserActionContextEnum.AMENDMENT_EXPIRATION_SCHEDULER).build()); + + List amendmentRequestList = applicationAmendmentRepository + .findAmendmentsDueForExpiration( + DateTimeUtil.DateServerToUTC(LocalDateTime.now()).with(LocalTime.MIN).plusSeconds(5)); + processAmendmentsForExpiration(amendmentRequestList); + log.info("Application Amendment Expiration scheduler completed successfully."); + } catch (Exception e) { + log.error("An error occurred during the Application Amendment Expiration scheduler: {}", e.getMessage(), e); + } + Utils.clearHttpServletRequest(); + } + + private void processAmendmentsForExpiration(List amendmentRequests) { + + log.info("Starting the process of expiring application amendments."); + amendmentRequests.forEach(request -> { + try { + ApplicationAmendmentRequestEntity oldAmendmentRequestEntity = Utils.getClonedEntityForData(request); + request.setStatus(ApplicationAmendmentRequestEnum.CLOSE.getValue()); + request = applicationAmendmentRepository.save(request); + + /** This code is responsible for adding a version history log for the "Update Application Amendment" operation. **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(httpServletRequest).actionType(VersionActionTypeEnum.UPDATE).oldData(oldAmendmentRequestEntity).newData(request).build()); + + emailNotificationDao.sendApplicationFailureNotificationEmail(request); + log.info("Updated status to CLOSED for ApplicationAmendmentRequest with ID: {}", request.getId()); + } catch (Exception e) { + log.error("Error expiring ApplicationAmendmentRequest with ID {}: {}", request.getId(), e.getMessage(), + e); + } + }); + log.info("Completed the process of updating expiring application amendments."); + + log.info("Starting the process of updating EndDate in ApplicationEvaluations."); + try { + Set applicationEvaluationIds = amendmentRequests.stream() + .map(request -> request.getApplicationEvaluationEntity().getId()).collect(Collectors.toSet()); + + Set evaluationsWithoutActiveAmendmentList = applicationAmendmentRepository + .findEvaluationsWithoutActiveAmendmentsByIds(applicationEvaluationIds); + evaluationsWithoutActiveAmendmentList.forEach(evaluation -> { + try { + applicationAmendmentRequestDao.calculateEndDateAndSuspensionDays(evaluation); + log.info("Updated EndDate and suspension days for ApplicationEvaluation with ID: {}", + evaluation.getId()); + } catch (Exception e) { + log.error("Error updating EndDate for ApplicationEvaluation with ID {}: {}", evaluation.getId(), + e.getMessage(), e); + } + }); + + log.info("Completed the process of updating EndDate in ApplicationEvaluations."); + } catch (Exception e) { + log.error("An error occurred while updating EndDate in ApplicationEvaluations: {}", e.getMessage(), e); + } + + } + +} diff --git a/src/main/java/net/gepafin/tendermanagement/scheduler/ApplicationEvaluationScheduler.java b/src/main/java/net/gepafin/tendermanagement/scheduler/ApplicationEvaluationScheduler.java index 54e641c9..94980dcd 100644 --- a/src/main/java/net/gepafin/tendermanagement/scheduler/ApplicationEvaluationScheduler.java +++ b/src/main/java/net/gepafin/tendermanagement/scheduler/ApplicationEvaluationScheduler.java @@ -3,42 +3,93 @@ package net.gepafin.tendermanagement.scheduler; import jakarta.servlet.http.HttpServletRequest; import net.gepafin.tendermanagement.entities.ApplicationEvaluationEntity; import net.gepafin.tendermanagement.enums.ApplicationEvaluationStatusTypeEnum; +import net.gepafin.tendermanagement.enums.UserActionContextEnum; +import net.gepafin.tendermanagement.enums.UserActionLogsEnum; import net.gepafin.tendermanagement.enums.VersionActionTypeEnum; +import net.gepafin.tendermanagement.model.request.UserActionRequest; import net.gepafin.tendermanagement.model.request.VersionHistoryRequest; import net.gepafin.tendermanagement.repositories.ApplicationEvaluationRepository; +import net.gepafin.tendermanagement.util.DateTimeUtil; import net.gepafin.tendermanagement.util.LoggingUtil; import net.gepafin.tendermanagement.util.Utils; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; import java.time.LocalDateTime; +import java.time.LocalTime; import java.util.List; +@Component public class ApplicationEvaluationScheduler { + @Autowired + private ApplicationEvaluationRepository applicationEvaluationRepository; - @Autowired - private ApplicationEvaluationRepository applicationEvaluationRepository; + @Autowired + private LoggingUtil loggingUtil; - @Autowired - private LoggingUtil loggingUtil; + @Autowired + private HttpServletRequest httpServletRequest; - @Autowired - private HttpServletRequest request; + private static final Logger log = LoggerFactory.getLogger(ApplicationEvaluationScheduler.class); - @Scheduled(cron = "0 0 1 * * ?") // Runs daily at midnight - public void updateExpiredEvaluations() { - LocalDateTime currentDate = LocalDateTime.now(); - List evaluations = applicationEvaluationRepository.findAllByIsDeletedFalseAndEndDateBefore(currentDate); + @Scheduled(cron = "0 0 2 * * ?") // Runs daily at midnight + public void updateExpiredEvaluations() { + log.info("Starting the Application Evaluation Expiration scheduler..."); + Utils.setHttpServletRequestForScheduler(); + try { + processExpiredEvaluation(); + log.info("Completed the process of updating expiring application evaluations."); + } catch (Exception e) { + log.error("An error occurred during the Application Evaluation Expiration scheduler: {}", e.getMessage(), + e); + } finally { + Utils.clearHttpServletRequest(); + } + } - for (ApplicationEvaluationEntity evaluation : evaluations) { - ApplicationEvaluationEntity oldApplicationEvaluationEntity = Utils.getClonedEntityForData(evaluation); - evaluation.setStatus(ApplicationEvaluationStatusTypeEnum.EXPIRED.getValue()); + private void processExpiredEvaluation() { + log.info("Starting the process of expiring application evaluations."); - /** This code is responsible for adding a version history log for the "Update Application Amendment" operation. **/ - loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplicationEvaluationEntity).newData(evaluation).build()); - } - applicationEvaluationRepository.saveAll(evaluations); - } - } + // Logging user action for the scheduler operation + loggingUtil.logUserActionWithoutToken( + UserActionRequest.builder().request(httpServletRequest).actionType(UserActionLogsEnum.SCHEDULER) + .actionContext(UserActionContextEnum.EVALUATION_EXPIRATION_SCHEDULER).build()); + try { + List evaluations = applicationEvaluationRepository + .findAllByIsDeletedFalseAndEndDateBefore( + DateTimeUtil.DateServerToUTC(LocalDateTime.now()).with(LocalTime.MIN).plusSeconds(5)); + log.info("Found {} evaluations to process for expiration.", evaluations.size()); + + for (ApplicationEvaluationEntity evaluation : evaluations) { + try { + log.debug("Processing evaluation with ID: {}", evaluation.getId()); + + ApplicationEvaluationEntity oldApplicationEvaluationEntity = Utils + .getClonedEntityForData(evaluation); + + evaluation.setStatus(ApplicationEvaluationStatusTypeEnum.EXPIRED.getValue()); + evaluation = applicationEvaluationRepository.save(evaluation); + + // Logging version history for the update operation + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(httpServletRequest) + .actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplicationEvaluationEntity) + .newData(evaluation).build()); + + log.info("Updated evaluation status to EXPIRED for ID: {}", evaluation.getId()); + } catch (Exception e) { + log.error("Error processing evaluation with ID: {}. Error: {}", evaluation.getId(), e.getMessage(), + e); + } + } + } catch (Exception e) { + log.error("An error occurred while fetching evaluations for expiration. Error: {}", e.getMessage(), e); + } + + } +} diff --git a/src/main/java/net/gepafin/tendermanagement/scheduler/NotificationScheduler.java b/src/main/java/net/gepafin/tendermanagement/scheduler/NotificationScheduler.java deleted file mode 100644 index 521726a9..00000000 --- a/src/main/java/net/gepafin/tendermanagement/scheduler/NotificationScheduler.java +++ /dev/null @@ -1,76 +0,0 @@ -package net.gepafin.tendermanagement.scheduler; - -import net.gepafin.tendermanagement.dao.ApplicationAmendmentRequestDao; -import net.gepafin.tendermanagement.dao.EmailNotificationDao; -import net.gepafin.tendermanagement.entities.ApplicationAmendmentRequestEntity; -import net.gepafin.tendermanagement.entities.ApplicationEntity; -import net.gepafin.tendermanagement.entities.ApplicationEvaluationEntity; -import net.gepafin.tendermanagement.entities.UserEntity; -import net.gepafin.tendermanagement.enums.ApplicationAmendmentRequestEnum; -import net.gepafin.tendermanagement.enums.ApplicationStatusTypeEnum; -import net.gepafin.tendermanagement.repositories.ApplicationAmendmentRequestRepository; -import net.gepafin.tendermanagement.repositories.ApplicationEvaluationRepository; -import net.gepafin.tendermanagement.repositories.ApplicationRepository; -import net.gepafin.tendermanagement.repositories.UserRepository; -import net.gepafin.tendermanagement.util.DateTimeUtil; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.scheduling.annotation.Scheduled; -import org.springframework.stereotype.Component; - -import java.time.LocalDateTime; -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; - -@Component -public class NotificationScheduler { - - @Autowired - UserRepository userRepository; - - @Autowired - ApplicationRepository applicationRepository; - - @Autowired - ApplicationAmendmentRequestRepository applicationAmendmentRepository; - - @Autowired - EmailNotificationDao emailNotificationDao; - - @Autowired - private ApplicationAmendmentRequestDao applicationAmendmentRequestDao; - - @Autowired - private ApplicationEvaluationRepository applicationEvaluationRepository; - - @Scheduled(cron = "0 0 1 * * ?") - void sendNotificationForRejectedApplicationToBeneficiary() { - - List applicationsList = applicationRepository.findByIsDeletedFalse(); - List amendmentRequestList = applicationAmendmentRepository.findByIsDeletedFalse(); - - LocalDateTime today = LocalDateTime.now(); - - for (ApplicationEntity application : applicationsList) { - List amendmentRequestEntities = applicationAmendmentRepository.findActiveAmendments(application.getId(), DateTimeUtil.DateServerToUTC(LocalDateTime.now())); - List applicationAmendmentRequestEntities = new ArrayList<>(); - if (amendmentRequestEntities != null && Boolean.FALSE.equals(amendmentRequestEntities.isEmpty())) { - for (ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity : amendmentRequestEntities) { - if (amendmentRequestEntities.size() == 1) { - applicationAmendmentRequestDao.calculateEndDateAndSuspensionDays(applicationAmendmentRequestEntity.getApplicationEvaluationEntity()); - } - application.setStatus(ApplicationStatusTypeEnum.REJECTED.getValue()); - applicationRepository.save(application); - applicationAmendmentRequestEntity.setStatus(ApplicationAmendmentRequestEnum.CLOSE.getValue()); - applicationAmendmentRepository.save(applicationAmendmentRequestEntity); - emailNotificationDao.sendApplicationFailureNotificationEmail(applicationAmendmentRequestEntity); - } - } - } - } - - private ApplicationAmendmentRequestEntity getAmendmentRequestForApplication(ApplicationEntity application, List amendmentRequestList) { - - return amendmentRequestList.stream().filter(request -> request.getApplicationId().equals(application.getId())).findFirst().orElse(null); - } -} diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationAmendmentRequestServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationAmendmentRequestServiceImpl.java index 4d3092a3..7329c5c3 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationAmendmentRequestServiceImpl.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationAmendmentRequestServiceImpl.java @@ -20,6 +20,7 @@ import net.gepafin.tendermanagement.web.rest.api.errors.ResourceNotFoundExceptio import net.gepafin.tendermanagement.web.rest.api.errors.Status; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import java.util.List; import java.util.Optional; @@ -45,6 +46,7 @@ public class ApplicationAmendmentRequestServiceImpl implements ApplicationAmendm } @Override + @Transactional(rollbackFor = Exception.class) public ApplicationAmendmentRequestResponse createApplicationAmendmentRequest(HttpServletRequest request, Long applicationEvaluationId , ApplicationAmendmentRequest applicationAmendmentRequest) { Optional entityOptional = applicationEvaluationRepository.findByIdAndIsDeletedFalse(applicationEvaluationId); entityOptional.ifPresent(applicationEvaluationEntity -> validator.validatePreInstructor(request, applicationEvaluationEntity.getUserId())); @@ -52,6 +54,7 @@ public class ApplicationAmendmentRequestServiceImpl implements ApplicationAmendm } @Override + @Transactional(rollbackFor = Exception.class) public void deleteApplicationAmendmentRequest(HttpServletRequest request, Long id) { ApplicationAmendmentRequestEntity amendment = applicationAmendmentRequestRepository.findByIdAndIsDeletedFalse(id) .orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND, @@ -86,6 +89,7 @@ public class ApplicationAmendmentRequestServiceImpl implements ApplicationAmendm } @Override + @Transactional(rollbackFor = Exception.class) public ApplicationAmendmentRequestResponse updateApplicationAmendment(HttpServletRequest request, Long id, ApplicationAmendmentRequestBean applicationAmendmentRequestBean) { ApplicationAmendmentRequestEntity amendment = applicationAmendmentRequestDao.validateApplicationAmendmentRequest(id); @@ -110,6 +114,7 @@ public class ApplicationAmendmentRequestServiceImpl implements ApplicationAmendm } @Override + @Transactional(rollbackFor = Exception.class) public ApplicationAmendmentRequestResponse closeAmendmentRequest(HttpServletRequest request, Long id, CloseAmendmentRequest closeAmendmentRequest) { ApplicationAmendmentRequestEntity amendment = applicationAmendmentRequestRepository.findByIdAndIsDeletedFalse(id) .orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND, @@ -123,6 +128,7 @@ public class ApplicationAmendmentRequestServiceImpl implements ApplicationAmendm } @Override + @Transactional(rollbackFor = Exception.class) public ApplicationAmendmentRequestResponse extendResponseDays(HttpServletRequest request, Long id, Long addedDays) { UserEntity user= validator.validateUser(request); return applicationAmendmentRequestDao.extendResponseDays(id, addedDays); @@ -132,6 +138,7 @@ public class ApplicationAmendmentRequestServiceImpl implements ApplicationAmendm return applicationAmendmentRequestDao.getAmendmentByApplicationId(request,applicationId,statuses); } @Override + @Transactional(rollbackFor = Exception.class) public ApplicationAmendmentRequestResponse updateApplicationAmendmentStatus(HttpServletRequest request, Long applicationAmendmentId, ApplicationAmendmentRequestEnum status) { return applicationAmendmentRequestDao.updateApplicationAmendmentStatus(applicationAmendmentId, status); diff --git a/src/main/java/net/gepafin/tendermanagement/util/LoggingUtil.java b/src/main/java/net/gepafin/tendermanagement/util/LoggingUtil.java index 53ed01cb..319795ec 100644 --- a/src/main/java/net/gepafin/tendermanagement/util/LoggingUtil.java +++ b/src/main/java/net/gepafin/tendermanagement/util/LoggingUtil.java @@ -134,8 +134,12 @@ public class LoggingUtil { try { VersionHistoryEntity history = new VersionHistoryEntity(); String token = tokenProvider.extractTokenFromRequest(versionHistoryRequest.getRequest()); - Claims claims = tokenProvider.getClaimsFromToken(token); - Long userId = claims.get(GepafinConstant.USER_ID, Long.class); + if(versionHistoryRequest.getRequest() != null && token != null) + { + Claims claims = tokenProvider.getClaimsFromToken(token); + Long userId = claims.get(GepafinConstant.USER_ID, Long.class); + history.setUserId(userId); + } String oldData = Utils.convertEntityToJsonForLogging(versionHistoryRequest.getOldData()); String newData = Utils.convertEntityToJsonForLogging(versionHistoryRequest.getNewData()); history.setUserActionId(userActionId); @@ -144,7 +148,6 @@ public class LoggingUtil { history.setNewData(newData); history.setRecordId(recordId); history.setTableName(tableName); - history.setUserId(userId); versionHistoryRepository.save(history); } catch (Exception e) { log.error("Error logging version history: {}", e.getMessage(), e); diff --git a/src/main/java/net/gepafin/tendermanagement/util/Utils.java b/src/main/java/net/gepafin/tendermanagement/util/Utils.java index 4949e5d5..7524c306 100644 --- a/src/main/java/net/gepafin/tendermanagement/util/Utils.java +++ b/src/main/java/net/gepafin/tendermanagement/util/Utils.java @@ -46,6 +46,9 @@ import net.gepafin.tendermanagement.web.rest.api.errors.FeignClientNotFoundExcep import net.gepafin.tendermanagement.web.rest.api.errors.FeignClientUnauthorizedException; import net.gepafin.tendermanagement.web.rest.api.errors.FeignClientValidationException; import org.springframework.http.MediaType; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; @@ -564,4 +567,17 @@ public class Utils { return null; } } + + public static void setHttpServletRequestForScheduler() { + MockHttpServletRequest mockRequest = new MockHttpServletRequest(); + mockRequest.setRequestURI("/scheduled"); + mockRequest.setMethod("POST"); + ServletRequestAttributes attributes = new ServletRequestAttributes(mockRequest); + RequestContextHolder.setRequestAttributes(attributes); + } + + public static void clearHttpServletRequest() { + // Clear the RequestContextHolder after task execution + RequestContextHolder.resetRequestAttributes(); + } } From 35669bae3969f8fe107631d2a970901a71ef3687 Mon Sep 17 00:00:00 2001 From: nisha Date: Thu, 28 Nov 2024 12:42:20 +0530 Subject: [PATCH 36/43] Update code --- .../ApplicationEvaluationScheduler.java | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/scheduler/ApplicationEvaluationScheduler.java b/src/main/java/net/gepafin/tendermanagement/scheduler/ApplicationEvaluationScheduler.java index 94980dcd..a0444349 100644 --- a/src/main/java/net/gepafin/tendermanagement/scheduler/ApplicationEvaluationScheduler.java +++ b/src/main/java/net/gepafin/tendermanagement/scheduler/ApplicationEvaluationScheduler.java @@ -40,8 +40,16 @@ public class ApplicationEvaluationScheduler { @Scheduled(cron = "0 0 2 * * ?") // Runs daily at midnight public void updateExpiredEvaluations() { log.info("Starting the Application Evaluation Expiration scheduler..."); - Utils.setHttpServletRequestForScheduler(); try { + + Utils.setHttpServletRequestForScheduler(); + + // Logging user action for the scheduler operation + loggingUtil.logUserActionWithoutToken( + UserActionRequest.builder().request(httpServletRequest).actionType(UserActionLogsEnum.SCHEDULER) + .actionContext(UserActionContextEnum.EVALUATION_EXPIRATION_SCHEDULER).build()); + + processExpiredEvaluation(); log.info("Completed the process of updating expiring application evaluations."); } catch (Exception e) { @@ -55,11 +63,7 @@ public class ApplicationEvaluationScheduler { private void processExpiredEvaluation() { log.info("Starting the process of expiring application evaluations."); - // Logging user action for the scheduler operation - loggingUtil.logUserActionWithoutToken( - UserActionRequest.builder().request(httpServletRequest).actionType(UserActionLogsEnum.SCHEDULER) - .actionContext(UserActionContextEnum.EVALUATION_EXPIRATION_SCHEDULER).build()); - + try { List evaluations = applicationEvaluationRepository .findAllByIsDeletedFalseAndEndDateBefore( From b7c381899ba59b8c20e233f9943d779c86d99d3b Mon Sep 17 00:00:00 2001 From: rajesh Date: Fri, 29 Nov 2024 18:50:03 +0530 Subject: [PATCH 37/43] updated code for vatcheck --- .../java/net/gepafin/tendermanagement/dao/VatCheckDao.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/VatCheckDao.java b/src/main/java/net/gepafin/tendermanagement/dao/VatCheckDao.java index 1a4c110d..52321b43 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/VatCheckDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/VatCheckDao.java @@ -65,9 +65,6 @@ public class VatCheckDao { URI baseUrl = URI.create(GepafinConstant.CHECK_VATNUMBER_V2_NEW_URL); ResponseEntity> response = vatCheckService.checkVatNumber(baseUrl, vatNumber, headers); - /** This code is responsible for creating user action logs for the "Download company delegation" operation. **/ - loggingUtil.logUserAction( - UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.VIEW).actionContext(UserActionContextEnum.CHECK_COMPANY_VAT_NUMBER).build()); if (response.getStatusCode() == HttpStatus.OK && response.hasBody()) { log.info("Successfully checked vat number"); From d397b3f7b7df8ea562107d76854e477999a29a70 Mon Sep 17 00:00:00 2001 From: nisha Date: Fri, 29 Nov 2024 20:44:18 +0530 Subject: [PATCH 38/43] Script for migrating deleted Documents --- .../tendermanagement/dao/DelegationDao.java | 22 +++--- .../tendermanagement/dao/DocumentDao.java | 35 ++++++--- .../repositories/DocumentRepository.java | 4 + .../service/AmazonS3Service.java | 13 +--- .../service/impl/AmazonS3ServiceImpl.java | 69 +++-------------- .../impl/S3ReUploadMigrationService.java | 74 ++++++++++++++----- .../UserSignedAndDelegationServiceImpl.java | 23 ++++-- .../web/rest/api/S3MigrationApi.java | 6 +- .../rest/api/UserSignedAndDelegationApi.java | 2 +- 9 files changed, 129 insertions(+), 119 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/DelegationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/DelegationDao.java index 6cba1b39..f5006e2f 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/DelegationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/DelegationDao.java @@ -202,14 +202,8 @@ public class DelegationDao { .findByUserIdAndUserWithCompanyIdAndStatus(userEntity.getId(), userWithCompanyEntity.getId(), UserCompanyDelegationStatusEnum.ACTIVE.getValue()); - UserCompanyDelegationEntity oldUserCompanyDelegationEntity = Utils.getClonedEntityForData(userCompanyDelegationEntity); if (userCompanyDelegationEntity != null) { - userCompanyDelegationEntity.setStatus(UserCompanyDelegationStatusEnum.INACTIVE.getValue()); - userCompanyDelegationRepository.save(userCompanyDelegationEntity); - - /** This code is responsible for adding a version history log for the "update user company delegation status" operation. **/ - loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldUserCompanyDelegationEntity) - .newData(userCompanyDelegationEntity).build()); + deleteDelegationFromS3(userCompanyDelegationEntity); } UploadFileOnAmazonS3Response uploadFileOnAmazonS3Response = uploadFileOnAmazonS3ForCompanyDelegation(file); userCompanyDelegationEntity = new UserCompanyDelegationEntity(); @@ -282,16 +276,22 @@ public class DelegationDao { .findByUserIdAndUserWithCompanyIdAndStatus(userEntity.getId(), userWithCompanyEntity.getId(), UserCompanyDelegationStatusEnum.ACTIVE.getValue()); companyDao.getUserWithCompany(userEntity.getId(), companyId); - //cloned entity for old data - UserCompanyDelegationEntity oldUserCompanyDelegation = Utils.getClonedEntityForData(userCompanyDelegationEntity); if (userCompanyDelegationEntity == null) { throw new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.DELEGATION_NOT_FOUND)); } - amazonS3Service.deleteDelegationfromS3(userCompanyDelegationEntity); + deleteDelegationFromS3(userCompanyDelegationEntity); + } + + public void deleteDelegationFromS3(UserCompanyDelegationEntity userCompanyDelegationEntity) { + UserCompanyDelegationEntity oldUserCompanyDelegation = Utils.getClonedEntityForData(userCompanyDelegationEntity); + String oldS3Path = userCompanyDelegationEntity.getFilePath(); + String newS3Path = s3ConfigBean.generateDocumentPathForDelegationAndSignedDocument(DocOtherSourceTypeEnum.DELETED_USER_DELEGATION); + UploadFileOnAmazonS3Response response = amazonS3Service.moveFile(userCompanyDelegationEntity.getFileName(), oldS3Path, newS3Path); + userCompanyDelegationEntity.setFileName(response.getFileName()); + userCompanyDelegationEntity.setFilePath(response.getFilePath()); userCompanyDelegationEntity.setStatus(UserCompanyDelegationStatusEnum.INACTIVE.getValue()); userCompanyDelegationRepository.save(userCompanyDelegationEntity); - /** This code is responsible for adding a version history log for the "Soft Deleting company delegation " operation. **/ loggingUtil.addVersionHistory( VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.SOFT_DELETE).oldData(oldUserCompanyDelegation).newData(userCompanyDelegationEntity) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/DocumentDao.java b/src/main/java/net/gepafin/tendermanagement/dao/DocumentDao.java index 1d83b2ba..b23e4785 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/DocumentDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/DocumentDao.java @@ -4,9 +4,7 @@ import lombok.extern.slf4j.Slf4j; import java.util.stream.Collectors; import jakarta.servlet.http.HttpServletRequest; -import net.gepafin.tendermanagement.enums.DocumentSourceTypeEnum; -import net.gepafin.tendermanagement.enums.UserActionContextEnum; -import net.gepafin.tendermanagement.enums.VersionActionTypeEnum; +import net.gepafin.tendermanagement.enums.*; import net.gepafin.tendermanagement.model.request.VersionHistoryRequest; import net.gepafin.tendermanagement.repositories.ApplicationRepository; import net.gepafin.tendermanagement.util.LoggingUtil; @@ -21,7 +19,6 @@ import net.gepafin.tendermanagement.constants.GepafinConstant; import net.gepafin.tendermanagement.entities.ApplicationEntity; import net.gepafin.tendermanagement.entities.CallEntity; import net.gepafin.tendermanagement.entities.DocumentEntity; -import net.gepafin.tendermanagement.enums.DocumentTypeEnum; import net.gepafin.tendermanagement.model.response.DocumentResponseBean; import net.gepafin.tendermanagement.model.response.UploadFileOnAmazonS3Response; import net.gepafin.tendermanagement.repositories.ApplicationAmendmentRequestRepository; @@ -188,7 +185,6 @@ public class DocumentDao { if(Boolean.TRUE.equals(documentEntity.getIsDeleted())){ return; } - DocumentEntity oldDocumentEntity = Utils.getClonedEntityForData(documentEntity); Long callId = null; Long applicationId = null; Long amendmentId = null; @@ -207,13 +203,8 @@ public class DocumentDao { callId = applicationEntity.getCall().getId(); } - amazonS3Service.deleteFileFromS3(documentEntity, callId, applicationId,amendmentId); - documentEntity.setIsDeleted(true); - documentRepository.save(documentEntity); + deleteFileFromS3(documentEntity, callId, applicationId,amendmentId); - /** This code is responsible for adding a version history log for the "Soft delete document" operation. **/ - loggingUtil.addVersionHistory( - VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.SOFT_DELETE).oldData(oldDocumentEntity).newData(documentEntity).build()); } public DocumentEntity validateDocument(Long id) { @@ -275,4 +266,26 @@ public class DocumentDao { DocumentEntity documentEntity = validateDocument(documentId); return callDao.convertToDocumentResponseBean(documentEntity); } + + public void deleteFileFromS3(DocumentEntity documentEntity, Long callId, Long applicationId,Long amendmentId) { + try { + + DocumentEntity oldDocumentEntity = Utils.getClonedEntityForData(documentEntity); + String oldS3Path = documentEntity.getFilePath(); + String newS3Path = s3ConfigBean.generateDocumentPathForOther(DocOtherSourceTypeEnum.valueOf("DELETED_" + documentEntity.getSource().toUpperCase()), callId, applicationId,amendmentId); + UploadFileOnAmazonS3Response response = amazonS3Service.moveFile(documentEntity.getFileName(), oldS3Path, newS3Path); + documentEntity.setFileName(response.getFileName()); + documentEntity.setFilePath(response.getFilePath()); + documentEntity.setIsDeleted(true); + documentRepository.save(documentEntity); + + /** This code is responsible for adding a version history log for the "Soft delete document" operation. **/ + loggingUtil.addVersionHistory( + VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.SOFT_DELETE).oldData(oldDocumentEntity).newData(documentEntity).build()); + log.info("File for document ID {} successfully moved to deleted folder.", documentEntity.getId()); + } catch (Exception e) { + log.error("Error moving file for document ID {} to deleted folder: {}", documentEntity.getId(), e.getMessage()); + throw new CustomValidationException(Status.VALIDATION_ERROR, "Error occurred while moving file to deleted folder."); + } + } } diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/DocumentRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/DocumentRepository.java index 684e2a3b..9e808114 100644 --- a/src/main/java/net/gepafin/tendermanagement/repositories/DocumentRepository.java +++ b/src/main/java/net/gepafin/tendermanagement/repositories/DocumentRepository.java @@ -28,6 +28,10 @@ public interface DocumentRepository extends JpaRepository @Query("SELECT d FROM DocumentEntity d WHERE d.isDeleted = false") List findAllByIsDeleteFalse(); + + @Query("SELECT d FROM DocumentEntity d WHERE d.isDeleted = true") + List findAllByIsDeleteTrue(); + List findAllByIdInAndIsDeletedFalse(Set documentIds); } diff --git a/src/main/java/net/gepafin/tendermanagement/service/AmazonS3Service.java b/src/main/java/net/gepafin/tendermanagement/service/AmazonS3Service.java index c9de1287..f9f22ae1 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/AmazonS3Service.java +++ b/src/main/java/net/gepafin/tendermanagement/service/AmazonS3Service.java @@ -1,7 +1,4 @@ package net.gepafin.tendermanagement.service; -import net.gepafin.tendermanagement.entities.DocumentEntity; -import net.gepafin.tendermanagement.entities.UserCompanyDelegationEntity; -import net.gepafin.tendermanagement.enums.DocOtherSourceTypeEnum; import org.springframework.stereotype.Component; import org.springframework.web.multipart.MultipartFile; @@ -20,14 +17,6 @@ AmazonS3Service { InputStream getFile(String s3Folder, String filePath) throws IOException; - String generateS3PathForDeletedDocument(DocOtherSourceTypeEnum typeOfDocument, Long callId, Long applicationId,Long amendmentId); - - String generateS3PathForDeletedDocumentForOther(); - - void moveFile(String bucketName, String oldPath, String newPath); - - void deleteDelegationfromS3(UserCompanyDelegationEntity userCompanyDelegationEntity); - - void deleteFileFromS3(DocumentEntity documentEntity, Long callId, Long applicationId,Long amendmentId); + UploadFileOnAmazonS3Response moveFile(String fileName, String oldPath, String newPath); } \ No newline at end of file diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/AmazonS3ServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/AmazonS3ServiceImpl.java index 5c251f19..3ff04c70 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/AmazonS3ServiceImpl.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/AmazonS3ServiceImpl.java @@ -61,9 +61,9 @@ public class AmazonS3ServiceImpl implements AmazonS3Service { @Value("${aws.s3.region}") private String region; - private String getBucketUrlPrefix() { - return "https://" + bucketName + ".s3." + region + ".amazonaws.com/"; - } + @Autowired + S3ReUploadMigrationService s3ReUploadMigrationService; + private String upload(String fileName, String s3Folder, MultipartFile file) throws IOException { @@ -146,32 +146,10 @@ public class AmazonS3ServiceImpl implements AmazonS3Service { } @Override - public String generateS3PathForDeletedDocument(DocOtherSourceTypeEnum typeOfDocument, Long callId, Long applicationId,Long amendmentId) { - try { - return s3ConfigBean.generateDocumentPathForOther(typeOfDocument, callId, applicationId,amendmentId); - } catch (IllegalArgumentException e) { - throw new CustomValidationException( - Status.VALIDATION_ERROR, - Translator.toLocale(GepafinConstant.S3_PATH_GENERATION_ERROR_MSG) - ); - } - } - - @Override - public String generateS3PathForDeletedDocumentForOther() { - try { - return s3ConfigBean.generateDocumentPathForDelegationAndSignedDocument(DocOtherSourceTypeEnum.DELETED_USER_DELEGATION); - } catch (IllegalArgumentException e) { - throw new CustomValidationException( - Status.VALIDATION_ERROR, - Translator.toLocale(GepafinConstant.S3_PATH_GENERATION_ERROR_MSG) - ); - } - } - - @Override - public void moveFile(String bucketName, String oldPath, String newPath) { + public UploadFileOnAmazonS3Response moveFile(String fileName, String oldPath, String newPath) { try { + newPath = cleanNewPath(oldPath, newPath); + oldPath = cleanOldPath(oldPath); log.info("Moving file from {} to {} in bucket {}", oldPath, newPath, bucketName); CopyObjectRequest copyRequest = new CopyObjectRequest(bucketName, oldPath, bucketName, newPath); @@ -180,6 +158,8 @@ public class AmazonS3ServiceImpl implements AmazonS3Service { s3Client.deleteObject(bucketName, oldPath); log.info("Original file deleted successfully: {}", oldPath); + String filePath = s3Url + newPath; + return UploadFileOnAmazonS3Response.builder().fileName(fileName).filePath(filePath).build(); } catch (AmazonServiceException e) { log.error("AWS service error while moving file: {}", e.getErrorMessage(), e); throw e; @@ -192,36 +172,11 @@ public class AmazonS3ServiceImpl implements AmazonS3Service { } } - @Override - public void deleteDelegationfromS3(UserCompanyDelegationEntity userCompanyDelegationEntity) { - String oldS3Path = userCompanyDelegationEntity.getFilePath(); - String newS3Path = generateS3PathForDeletedDocumentForOther() - + "/" + oldS3Path.substring(oldS3Path.lastIndexOf("/") + 1); - - String bucketUrlPrefix = getBucketUrlPrefix(); - if (oldS3Path.startsWith(bucketUrlPrefix)) { - oldS3Path = oldS3Path.replace(bucketUrlPrefix, ""); - } - moveFile(bucketName, oldS3Path, newS3Path); - log.info("File for company ID {} successfully moved to deleted folder.", userCompanyDelegationEntity.getId()); + private String cleanNewPath(String oldPath, String newPath) { + return newPath + "/" + oldPath.substring(oldPath.lastIndexOf("/") + 1); } - @Override - public void deleteFileFromS3(DocumentEntity documentEntity, Long callId, Long applicationId,Long amendmentId) { - try { - String oldS3Path = documentEntity.getFilePath(); - String newS3Path = generateS3PathForDeletedDocument(DocOtherSourceTypeEnum.valueOf("DELETED_" + documentEntity.getSource().toUpperCase()), callId, applicationId,amendmentId) - + "/" + oldS3Path.substring(oldS3Path.lastIndexOf("/") + 1); - String bucketUrlPrefix = getBucketUrlPrefix(); - if (oldS3Path.startsWith(bucketUrlPrefix)) { - oldS3Path = oldS3Path.replace(bucketUrlPrefix, ""); - } - - moveFile(bucketName, oldS3Path, newS3Path); - log.info("File for document ID {} successfully moved to deleted folder.", documentEntity.getId()); - } catch (Exception e) { - log.error("Error moving file for document ID {} to deleted folder: {}", documentEntity.getId(), e.getMessage()); - throw new CustomValidationException(Status.VALIDATION_ERROR, "Error occurred while moving file to deleted folder."); - } + private String cleanOldPath(String oldPath) { + return oldPath.replace(s3Url, ""); } } \ No newline at end of file diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/S3ReUploadMigrationService.java b/src/main/java/net/gepafin/tendermanagement/service/impl/S3ReUploadMigrationService.java index eefe4706..23b8fd59 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/S3ReUploadMigrationService.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/S3ReUploadMigrationService.java @@ -7,12 +7,17 @@ import com.amazonaws.services.s3.AmazonS3Client; import com.amazonaws.services.s3.model.GetObjectRequest; import com.amazonaws.services.s3.model.ObjectMetadata; import lombok.extern.slf4j.Slf4j; +import net.gepafin.tendermanagement.dao.DocumentDao; import net.gepafin.tendermanagement.dao.S3PathConfig; +import net.gepafin.tendermanagement.entities.ApplicationEntity; import net.gepafin.tendermanagement.entities.DocumentEntity; import net.gepafin.tendermanagement.enums.DocumentSourceTypeEnum; +import net.gepafin.tendermanagement.repositories.ApplicationAmendmentRequestRepository; import net.gepafin.tendermanagement.repositories.ApplicationRepository; import net.gepafin.tendermanagement.repositories.ApplicationSignedDocumentRepository; import net.gepafin.tendermanagement.repositories.DocumentRepository; +import net.gepafin.tendermanagement.service.AmazonS3Service; +import net.gepafin.tendermanagement.service.ApplicationService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; @@ -50,13 +55,35 @@ public class S3ReUploadMigrationService { @Autowired private AmazonS3 amazonS3; + @Autowired + ApplicationService applicationService; + @Value("${aws.s3.url}") private String s3Url; + @Autowired + AmazonS3Service amazonS3Service; + + @Value("${aws.s3.bucket.name}") + private String bucketName; + + @Value("${aws.s3.region}") + private String region; + + @Autowired + private ApplicationAmendmentRequestRepository applicationAmendmentRequestRepository; + + @Autowired + private DocumentDao documentDao; + + private boolean migrationCompleted = false; public String reUploadAndMigrateDocuments(String providedKey) { + Long totalDocuments=0L; + Long failedDocuments=0L; + Long processDocuments=0L; if (migrationCompleted) { return "Migration already completed."; } @@ -66,26 +93,48 @@ public class S3ReUploadMigrationService { return "Invalid or missing migration key."; } - List documents = documentRepository.findAllByIsDeleteFalse(); + List documents = documentRepository.findAllByIsDeleteTrue(); + totalDocuments = Long.valueOf(documents.size()); if (documents.isEmpty()) { return "No documents found to migrate."; } for (DocumentEntity document : documents) { - String oldUrl = document.getFilePath(); // This should contain the full URL - log.info("Processing {}", oldUrl); - + log.info("Processing for the Document id and url:{} ",document.getId(),document.getFilePath()); try { - File localFile = downloadFileFromS3(oldUrl); - String newKey = generateNewS3Path(document); // Make sure this generates the correct new path - String uploadedPath = uploadFileToNewBucket(localFile, newKey); - updateDocumentPathAndNameEntry(document, uploadedPath); + + Long callId = null; + Long applicationId = null; + Long amendmentId = null; + + if (DocumentSourceTypeEnum.CALL.getValue().equalsIgnoreCase(document.getSource())) { + callId = document.getSourceId(); + } else if (DocumentSourceTypeEnum.APPLICATION.getValue().equalsIgnoreCase(document.getSource())) { + applicationId = document.getSourceId(); + ApplicationEntity applicationEntity = applicationService.validateApplication(applicationId); + callId = applicationEntity.getCall().getId(); + } + else if(DocumentSourceTypeEnum.AMENDMENT.getValue().equalsIgnoreCase(document.getSource())){ + amendmentId = document.getSourceId(); + ApplicationEntity applicationEntity = applicationAmendmentRequestRepository.findApplicationByAmendmentId(amendmentId); + applicationId = applicationEntity.getId(); + callId = applicationEntity.getCall().getId(); + } + + documentDao.deleteFileFromS3(document,callId,applicationId,amendmentId); + processDocuments++; + } catch (Exception e) { log.error("Error processing document {}: {}", document.getId(), e.getMessage()); + failedDocuments++; } } + log.info("Total Documents Fetched ",totalDocuments); + log.info("Total Process Documents :{}",processDocuments); + log.info("Total Failed Documents :{}",failedDocuments); return "Migrated Successfully."; + } private boolean isValidKey(String providedKey) { @@ -177,13 +226,4 @@ public class S3ReUploadMigrationService { return parts[parts.length - 1]; } - - private void updateDocumentPathAndNameEntry(DocumentEntity document, String newPath) { - - String fileName = extractFileName(newPath); - document.setFilePath(newPath); - document.setFileName(fileName); - documentRepository.save(document); - log.info("Migrated document ID: {} to new path: {}", document.getId(), newPath); - } } diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/UserSignedAndDelegationServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/UserSignedAndDelegationServiceImpl.java index d66f9aaa..d5bd4c3c 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/UserSignedAndDelegationServiceImpl.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/UserSignedAndDelegationServiceImpl.java @@ -6,6 +6,7 @@ import com.amazonaws.services.s3.AmazonS3Client; import com.amazonaws.services.s3.model.GetObjectRequest; import com.amazonaws.services.s3.model.ObjectMetadata; import lombok.extern.slf4j.Slf4j; +import net.gepafin.tendermanagement.dao.DelegationDao; import net.gepafin.tendermanagement.dao.S3PathConfig; import net.gepafin.tendermanagement.entities.ApplicationSignedDocumentEntity; import net.gepafin.tendermanagement.entities.UserCompanyDelegationEntity; @@ -56,10 +57,16 @@ public class UserSignedAndDelegationServiceImpl { @Value("${aws.s3.url}") private String s3Url; + @Autowired + private DelegationDao delegationDao; + private boolean migrationCompleted = false; public String migrateUserDelegatedDocuments(String providedKey) { + Long totalDocuments=0L; + Long failedDocuments=0L; + Long processDocuments=0L; if (migrationCompleted) { return "Migration already completed."; } @@ -69,25 +76,27 @@ public class UserSignedAndDelegationServiceImpl { return "Invalid or missing migration key."; } - List documents = userCompanyDelegationRepository.findAllByStatus("ACTIVE"); - + List documents = userCompanyDelegationRepository.findAllByStatus("INACTIVE"); + totalDocuments = Long.valueOf(documents.size()); if (documents.isEmpty()) { return "No documents found to migrate."; } for (UserCompanyDelegationEntity document : documents) { String oldUrl = document.getFilePath(); - log.info("Processing user designated document: {}", oldUrl); + log.info("Processing user designated document and old Url: {}", document.getId(),oldUrl); try { - File localFile = downloadFileFromS3(oldUrl); - String newKey = generateNewS3PathForDelegationDoc(); - String uploadedPath = uploadFileToNewBucket(localFile, newKey); - updateDelegatedDocumentPathAndNameEntry(document, uploadedPath); + delegationDao.deleteDelegationFromS3(document); + processDocuments++; } catch (Exception e) { log.error("Error processing user designated document {}: {}", document.getId(), e.getMessage()); + failedDocuments++; } } + log.info("Total Documents Fetched:{} ",totalDocuments); + log.info("Total Process Documents :{}",processDocuments); + log.info("Total Failed Documents :{}",failedDocuments); return "Migrated"; } diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/S3MigrationApi.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/S3MigrationApi.java index 4a4d3eb1..be771101 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/S3MigrationApi.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/S3MigrationApi.java @@ -5,9 +5,9 @@ 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.validation.Valid; + import net.gepafin.tendermanagement.web.rest.api.errors.ErrorConstants; -import org.springframework.data.repository.query.Param; + import org.springframework.http.MediaType; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.PathVariable; @@ -16,7 +16,7 @@ import org.springframework.web.bind.annotation.PutMapping; @Validated public interface S3MigrationApi { - @Operation(summary = "Api to migrate S3 doc to db and update s3 files as per specified folder.", responses = { @ApiResponse(responseCode = "200", description = "OK"), + @Operation(summary = "Api to migrate deleted documents to the deleted Folder ", 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 = { diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/UserSignedAndDelegationApi.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/UserSignedAndDelegationApi.java index 2a3978a1..94372dfa 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/UserSignedAndDelegationApi.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/UserSignedAndDelegationApi.java @@ -16,7 +16,7 @@ import org.springframework.web.bind.annotation.PostMapping; @Validated public interface UserSignedAndDelegationApi { - @Operation(summary = "Api to migrate S3 doc to db and user-delegated folder", responses = { @ApiResponse(responseCode = "200", description = "OK"), + @Operation(summary = "Api to migrate S3 user-delegated deleted doc to deleted folder", 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 = { From 30d1e22684520fb0cef523c92fdf2b9293b3aac9 Mon Sep 17 00:00:00 2001 From: nisha Date: Mon, 2 Dec 2024 12:35:36 +0530 Subject: [PATCH 39/43] Updated Code --- .../enums/UserActionLogsEnum.java | 3 ++- .../web/rest/api/S3MigrationApi.java | 3 ++- .../web/rest/api/UserSignedAndDelegationApi.java | 3 ++- .../rest/api/impl/S3MigrationApiController.java | 15 ++++++++++++++- ...serSignedAndDelegationMigrationController.java | 14 +++++++++++++- 5 files changed, 33 insertions(+), 5 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/enums/UserActionLogsEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/UserActionLogsEnum.java index 6fdd86f5..555d3298 100644 --- a/src/main/java/net/gepafin/tendermanagement/enums/UserActionLogsEnum.java +++ b/src/main/java/net/gepafin/tendermanagement/enums/UserActionLogsEnum.java @@ -11,7 +11,8 @@ public enum UserActionLogsEnum { INSERT("INSERT"), DOWNLOAD("DOWNLOAD"), UPLOAD("UPLOAD"), - SCHEDULER("SCHEDULER"); + SCHEDULER("SCHEDULER"), + SCRIPT("SCRIPT"); private final String value; diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/S3MigrationApi.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/S3MigrationApi.java index be771101..75039427 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/S3MigrationApi.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/S3MigrationApi.java @@ -6,6 +6,7 @@ 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 net.gepafin.tendermanagement.web.rest.api.errors.ErrorConstants; import org.springframework.http.MediaType; @@ -24,5 +25,5 @@ public interface S3MigrationApi { @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { @ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) }) @PutMapping(value = "/{key}", produces = { "application/json" }) - String reUploadAndMigrateDocuments(@Parameter(description = "The secret key", required = true) @PathVariable("key") String key); + String reUploadAndMigrateDocuments(HttpServletRequest request, @Parameter(description = "The secret key", required = true) @PathVariable("key") String key); } diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/UserSignedAndDelegationApi.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/UserSignedAndDelegationApi.java index 94372dfa..2cee9b76 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/UserSignedAndDelegationApi.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/UserSignedAndDelegationApi.java @@ -5,6 +5,7 @@ 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.web.rest.api.errors.ErrorConstants; import org.springframework.data.repository.query.Param; @@ -24,7 +25,7 @@ public interface UserSignedAndDelegationApi { @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { @ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) }) @GetMapping(value = "/{key}", produces = { "application/json" }) - String migrateUserDelegatedDocuments(@Parameter(description = "The secret key", required = true) @PathVariable("key") String key); + String migrateUserDelegatedDocuments(HttpServletRequest request, @Parameter(description = "The secret key", required = true) @PathVariable("key") String key); @Operation(summary = "Api to migrate S3 doc to user-signed.", responses = { @ApiResponse(responseCode = "200", description = "OK"), @ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/S3MigrationApiController.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/S3MigrationApiController.java index 7e58800e..c2b5affb 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/S3MigrationApiController.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/S3MigrationApiController.java @@ -1,6 +1,11 @@ package net.gepafin.tendermanagement.web.rest.api.impl; +import jakarta.servlet.http.HttpServletRequest; +import net.gepafin.tendermanagement.enums.UserActionContextEnum; +import net.gepafin.tendermanagement.enums.UserActionLogsEnum; +import net.gepafin.tendermanagement.model.request.UserActionRequest; import net.gepafin.tendermanagement.service.impl.S3ReUploadMigrationService; +import net.gepafin.tendermanagement.util.LoggingUtil; import net.gepafin.tendermanagement.web.rest.api.S3MigrationApi; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; @@ -12,8 +17,16 @@ public class S3MigrationApiController implements S3MigrationApi { @Autowired S3ReUploadMigrationService s3MigrationService; + + @Autowired + LoggingUtil loggingUtil; + @Override - public String reUploadAndMigrateDocuments(String providedKey) { + public String reUploadAndMigrateDocuments(HttpServletRequest request,String providedKey) { + + /** This code is responsible for creating user action logs for the "upload document for call or application" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.SCRIPT).actionContext(UserActionContextEnum.GET_DOCUMENT).build()); + return s3MigrationService.reUploadAndMigrateDocuments(providedKey); } } diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/S3UserSignedAndDelegationMigrationController.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/S3UserSignedAndDelegationMigrationController.java index 061b731b..e18159c6 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/S3UserSignedAndDelegationMigrationController.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/S3UserSignedAndDelegationMigrationController.java @@ -1,6 +1,11 @@ package net.gepafin.tendermanagement.web.rest.api.impl; +import jakarta.servlet.http.HttpServletRequest; +import net.gepafin.tendermanagement.enums.UserActionContextEnum; +import net.gepafin.tendermanagement.enums.UserActionLogsEnum; +import net.gepafin.tendermanagement.model.request.UserActionRequest; import net.gepafin.tendermanagement.service.impl.UserSignedAndDelegationServiceImpl; +import net.gepafin.tendermanagement.util.LoggingUtil; import net.gepafin.tendermanagement.web.rest.api.UserSignedAndDelegationApi; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; @@ -13,8 +18,15 @@ public class S3UserSignedAndDelegationMigrationController implements UserSignedA @Autowired UserSignedAndDelegationServiceImpl userSignedAndDelegationService; + @Autowired + LoggingUtil loggingUtil; + @Override - public String migrateUserDelegatedDocuments(String providedKey) { + public String migrateUserDelegatedDocuments(HttpServletRequest request,String providedKey) { + + /** This code is responsible for creating user action logs for the "upload document for call or application" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.SCRIPT).actionContext(UserActionContextEnum.GET_DOCUMENT).build()); + return userSignedAndDelegationService.migrateUserDelegatedDocuments(providedKey); } @Override From 346b5504660666b6eb7146d72b15416c4898fb60 Mon Sep 17 00:00:00 2001 From: rajesh Date: Tue, 3 Dec 2024 15:39:30 +0530 Subject: [PATCH 40/43] Updated code --- .../dao/ApplicationEvaluationDao.java | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java index fefe1469..7c25401b 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java @@ -264,7 +264,8 @@ public class ApplicationEvaluationDao { Optional formFieldEntityOptional = applicationFormFieldRepository .findByFieldIdAndApplicationFormIdAndApplicationFormApplicationId(formFieldId, applicationFormId, applicationId); - if (formFieldEntityOptional.isPresent()) { + if (formFieldEntityOptional.isPresent() && formFieldEntityOptional.get().getFieldValue()!=null && Boolean.FALSE.equals(formFieldEntityOptional.get() + .getFieldValue().isEmpty())) { String[] documentIds = formFieldEntityOptional.get().getFieldValue().split(","); List documentResponseBeans = new ArrayList<>(); @@ -815,6 +816,10 @@ public class ApplicationEvaluationDao { ObjectMapper objectMapper = new ObjectMapper(); findFormFieldValue(applicationId, formFieldId).ifPresent(formField -> { Object value = formField.getFieldValue(); + if (value == null) { + mappedField.setFieldValue(null); + return; + } List labels = new ArrayList<>(); if (value instanceof String) { String fieldValue = (String) value; @@ -1151,7 +1156,7 @@ public class ApplicationEvaluationDao { List documentResponseBeans = new ArrayList<>(); findFormFieldValue(applicationId, criteriaFormField.getFormFieldId()).ifPresent(formField -> { String fieldValue = formField.getFieldValue(); - if (fieldValue != null) { + if (fieldValue != null && (Boolean.FALSE.equals(fieldValue.isEmpty()))) { String[] fieldValues = fieldValue.split(","); for (String value : fieldValues) { Long documentId = Long.valueOf(value.trim()); @@ -1183,7 +1188,10 @@ public class ApplicationEvaluationDao { findFormFieldValue(applicationId, criteriaFormField.getFormFieldId()).ifPresent(formField -> { Object value = formField.getFieldValue(); List labels = new ArrayList<>(); - + if (value == null) { + mappedField.setFieldValue(null); + return; + } if (value instanceof String) { List parsedValue = parseJsonValue((String) value, objectMapper); addLabelsFromParsedValues(parsedValue, contentResponseBean, labels); @@ -1268,7 +1276,7 @@ public class ApplicationEvaluationDao { if (optionalFormField.isPresent()) { ApplicationFormFieldEntity formField = optionalFormField.get(); - if (formField.getFieldValue() != null) { + if (formField.getFieldValue() != null &&(Boolean.FALSE.equals(formField.getFieldValue().isEmpty()))) { FieldResponse fieldResponse = new FieldResponse(); fieldResponse.setId(fieldId); String label = null; From c1a3e12e68d1eb9b33fcfce8eacbb9bfbece9ad7 Mon Sep 17 00:00:00 2001 From: piyushkag Date: Tue, 3 Dec 2024 19:29:31 +0530 Subject: [PATCH 41/43] Template issue. --- .../dao/EmailNotificationDao.java | 154 ++++++++++++------ .../db/changelog/db.changelog-1.0.0.xml | 7 +- ...nt_mail_notification_mail_03_12_2024_1.sql | 26 +++ 3 files changed, 133 insertions(+), 54 deletions(-) create mode 100644 src/main/resources/db/dump/update_system_email_template_for_updating_amendment_mail_notification_mail_03_12_2024_1.sql diff --git a/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java index 70f90f3c..c6a2d14b 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java @@ -9,9 +9,13 @@ import net.gepafin.tendermanagement.enums.EmailEntityTypeEnum; import net.gepafin.tendermanagement.enums.RecipientTypeEnum; import net.gepafin.tendermanagement.enums.StatusTypeEnum; import net.gepafin.tendermanagement.entities.*; +import net.gepafin.tendermanagement.model.request.ApplicationAmendmentRequest; import net.gepafin.tendermanagement.model.request.EmailConfig; import net.gepafin.tendermanagement.model.request.EmailLogRequest; +import net.gepafin.tendermanagement.model.response.AmendmentFormFieldResponse; import net.gepafin.tendermanagement.model.response.SystemEmailTemplateResponse; +import net.gepafin.tendermanagement.repositories.ApplicationFormFieldRepository; +import net.gepafin.tendermanagement.repositories.ApplicationFormRepository; import net.gepafin.tendermanagement.repositories.EmailLogRepository; import net.gepafin.tendermanagement.repositories.HubRepository; import net.gepafin.tendermanagement.service.*; @@ -27,6 +31,8 @@ import org.springframework.stereotype.Component; import java.time.LocalDateTime; import java.util.*; +import static net.gepafin.tendermanagement.dao.ApplicationAmendmentRequestDao.filterByName; + @Component public class EmailNotificationDao { @@ -40,7 +46,7 @@ public class EmailNotificationDao { @Autowired private UserService userService; - + @Autowired private HubService hubService; @@ -55,91 +61,133 @@ public class EmailNotificationDao { @Autowired private EmailLogRepository emailLogRepository; - + @Autowired private CompanyService companyService; + @Autowired + private ApplicationFormRepository applicationFormRepository; - private void sendEmail(ApplicationEntity applicationEntity, SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum templateType, - Map bodyPlaceholders, List additionalRecipients,Long amendmentId) { + @Autowired + private ApplicationFormFieldRepository applicationFormFieldRepository; + + private void sendEmail(ApplicationEntity applicationEntity, SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum templateType, Map bodyPlaceholders, + List additionalRecipients, Long amendmentId) { HubEntity hubEntity = hubService.valdateHub(applicationEntity.getHubId()); - String service = determineService(applicationEntity.getHubId()); - String legalMail = service.equals("Gepafin S.p.a.") ? "bandi.gepafin@legalmail.it" : "bandi.sviluppumbria@legalmail.it"; +// String service = determineService(applicationEntity.getHubId()); +// String legalMail = service.equals("Gepafin S.p.a.") ? "bandi.gepafin@legalmail.it" : "bandi.sviluppumbria@legalmail.it"; SystemEmailTemplateResponse systemEmailTemplateResponse = systemEmailTemplatesService.retrieveTemplateByTypeAndCall(templateType, hubEntity, null); Map subjectPlaceholders = new HashMap<>(); - CompanyEntity company=companyService.validateCompany(applicationEntity.getCompanyId()); + CompanyEntity company = companyService.validateCompany(applicationEntity.getCompanyId()); subjectPlaceholders.put("{{call_name}}", applicationEntity.getCall().getName()); subjectPlaceholders.put("{{company_name}}", company.getCompanyName()); - bodyPlaceholders.put("{{legal_mail}}", legalMail); +// bodyPlaceholders.put("{{legal_mail}}", legalMail); String subject = Utils.replacePlaceholders(systemEmailTemplateResponse.getSubject(), subjectPlaceholders); String body = Utils.replacePlaceholders(systemEmailTemplateResponse.getHtmlContent(), bodyPlaceholders); UserEntity userEntity = userService.validateUser(applicationEntity.getUserId()); List recipientEmails = getRecipientEmails(applicationEntity, userEntity, additionalRecipients); - EmailLogRequest emailLogRequest=emailLogDao.createEmailLogRequest(systemEmailTemplateResponse.getEmailScenario(), RecipientTypeEnum.BENEFICIARY,userEntity.getBeneficiary().getId(),Utils.listToCommaSeparatedString(recipientEmails),userEntity.getId(),applicationEntity.getId(),amendmentId ,applicationEntity.getCall().getId()); - sendMail(applicationEntity.getHubId(), subject, body, recipientEmails,emailLogRequest); + EmailLogRequest emailLogRequest = emailLogDao.createEmailLogRequest(systemEmailTemplateResponse.getEmailScenario(), RecipientTypeEnum.BENEFICIARY, 1L, + Utils.listToCommaSeparatedString(recipientEmails), userEntity.getId(), applicationEntity.getId(), amendmentId, applicationEntity.getCall().getId()); + sendMail(applicationEntity.getHubId(), subject, body, recipientEmails, emailLogRequest); } private List getRecipientEmails(ApplicationEntity applicationEntity, UserEntity userEntity, List additionalRecipients) { + List recipientEmails = new ArrayList<>(); - CompanyEntity company=companyService.validateCompany(applicationEntity.getCompanyId()); - String companyEmail = company.getEmail(); - String contactEmail = company.getContactEmail(); - - if (companyEmail != null && !companyEmail.isEmpty()) { - recipientEmails.add(companyEmail); - } - if (contactEmail != null && !contactEmail.isEmpty() && !contactEmail.equals(companyEmail)) { - recipientEmails.add(contactEmail); - } - - if (userEntity.getBeneficiary().getEmail() != null) { - recipientEmails.add(userEntity.getBeneficiary().getEmail()); - } - if (additionalRecipients != null) { - recipientEmails.addAll(additionalRecipients); - } + CompanyEntity company = companyService.validateCompany(applicationEntity.getCompanyId()); + // String companyEmail = company.getEmail(); + // String contactEmail = company.getContactEmail(); + // + // if (companyEmail != null && !companyEmail.isEmpty()) { + // recipientEmails.add(companyEmail); + // } + // if (contactEmail != null && !contactEmail.isEmpty() && !contactEmail.equals(companyEmail)) { + // recipientEmails.add(contactEmail); + // } + // + // if (userEntity.getBeneficiary().getEmail() != null) { + // recipientEmails.add(userEntity.getBeneficiary().getEmail()); + // } + // if (additionalRecipients != null) { + // recipientEmails.addAll(additionalRecipients); + // } + recipientEmails.add("piyush1.kag1@gmail.com"); return recipientEmails; } +// +// private String determineService(Long hubId) { +// +// HubEntity hub = hubRepository.findById(hubId).orElseThrow(() -> new IllegalArgumentException("Invalid Hub ID: " + hubId)); +// return hub.getEmailServiceType().equalsIgnoreCase("MAILGUN_SERVICE") ? "Sviluppumbria" : "Gepafin S.p.a."; +// } + public void sendMailToNotifyBeneficiaryRegardingNewAmendment(ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity) { - private String determineService(Long hubId) { - - HubEntity hub = hubRepository.findById(hubId).orElseThrow(() -> new IllegalArgumentException("Invalid Hub ID: " + hubId)); - return hub.getEmailServiceType().equalsIgnoreCase("MAILGUN_SERVICE") ? "Gepafin S.p.a." : "Sviluppumbria"; - } - - public void sendMailToNotifyBeneficiaryRegardingNewAmendment(ApplicationAmendmentRequestEntity applicationAmendmentRequest) { - - ApplicationEntity applicationEntity = applicationService.validateApplication(applicationAmendmentRequest.getApplicationId()); + ApplicationEntity applicationEntity = applicationService.validateApplication(applicationAmendmentRequestEntity.getApplicationId()); Map bodyPlaceholders = new HashMap<>(); bodyPlaceholders.put("{{call_name}}", applicationEntity.getCall().getName()); - bodyPlaceholders.put("{{protocol_number}}", applicationAmendmentRequest.getProtocol().getProtocolNumber().toString()); - bodyPlaceholders.put("{{protocol_date}}", DateTimeUtil.formatLocalDateTime(applicationAmendmentRequest.getProtocol().getCreatedDate(), GepafinConstant.DD_MM_YYYY)); - bodyPlaceholders.put("{{protocol_time}}", DateTimeUtil.parseLocalTimeToString(applicationAmendmentRequest.getProtocol().getTime(), GepafinConstant.HH_MM_SS)); - String formFieldsJson = applicationAmendmentRequest.getFormFields(); - ObjectMapper objectMapper = new ObjectMapper(); + bodyPlaceholders.put("{{protocol_number}}", applicationAmendmentRequestEntity.getProtocol().getProtocolNumber().toString()); + bodyPlaceholders.put("{{protocol_date}}", DateTimeUtil.formatLocalDateTime(applicationAmendmentRequestEntity.getProtocol().getCreatedDate(), GepafinConstant.DD_MM_YYYY)); + bodyPlaceholders.put("{{protocol_time}}", DateTimeUtil.parseLocalTimeToString(applicationAmendmentRequestEntity.getProtocol().getTime(), GepafinConstant.HH_MM_SS)); try { - List> formFields = objectMapper.readValue(formFieldsJson, new TypeReference>>() { - }); - //• + // Retrieve forms and initialize required collections + List forms = applicationFormRepository.findByApplicationId(applicationEntity.getId()); + List allFormFields = new ArrayList<>(); StringBuilder bulletPoints = new StringBuilder(); - for (Map field : formFields) { - String label = (String) field.get("label"); - boolean selected = (boolean) field.get("selected"); - if (!selected) { - bulletPoints.append("• ").append(label).append("\n"); - } + + // Extract data from forms + for (ApplicationFormEntity form : forms) { + String content = form.getForm().getContent(); + List> result = filterByName(content, "fileupload"); + allFormFields.addAll(getIdAndLabelFromResult(result)); } + + // Process allFormFields and generate bullet points + for (AmendmentFormFieldResponse field : allFormFields) { + // Build bullet points + bulletPoints.append(field.getLabel()); + bulletPoints.append("\n"); + } + // Add the generated bullet points to placeholders bodyPlaceholders.put("{{form_dataInput}}", bulletPoints.toString()); } catch (Exception e) { - log.error("Failed to parse form fields JSON: ", e); + log.error("Failed to process form fields: ", e); } - bodyPlaceholders.put("{{note}}", applicationAmendmentRequest.getNote()); - sendEmail(applicationEntity, SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum.DOCUMENTATION_INTEGRATION_REQUEST, bodyPlaceholders, null,applicationAmendmentRequest.getId()); + + + bodyPlaceholders.put("{{note}}", applicationAmendmentRequestEntity.getNote()); + sendEmail(applicationEntity, SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum.DOCUMENTATION_INTEGRATION_REQUEST, bodyPlaceholders, null, + applicationAmendmentRequestEntity.getId()); + } + + public List getIdAndLabelFromResult(List> result) { + List formFieldResponses = new ArrayList<>(); + + for (Map item : result) { + AmendmentFormFieldResponse formFieldResponse = new AmendmentFormFieldResponse(); + formFieldResponse.setFieldId((String) item.get("id")); + + // Extract "label" value from the "settings" array + List> settings = (List>) item.get("settings"); + String label = settings.stream() + .filter(setting -> "label".equals(setting.get("name"))) + .map(setting -> (String) setting.get("value")) + .findFirst() + .orElse(""); // Default to empty string if not found + + if (label == null || label.trim().isEmpty()) { + continue; + } + + formFieldResponse.setLabel(label); // Set the label as fieldValue + formFieldResponses.add(formFieldResponse); + } + + return formFieldResponses; } public void sendApplicationFailureNotificationEmail(ApplicationAmendmentRequestEntity amendmentRequest) { 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 52a7dae3..61d8101f 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 @@ -1961,5 +1961,10 @@ - + + + + + diff --git a/src/main/resources/db/dump/update_system_email_template_for_updating_amendment_mail_notification_mail_03_12_2024_1.sql b/src/main/resources/db/dump/update_system_email_template_for_updating_amendment_mail_notification_mail_03_12_2024_1.sql new file mode 100644 index 00000000..3e4e8e30 --- /dev/null +++ b/src/main/resources/db/dump/update_system_email_template_for_updating_amendment_mail_notification_mail_03_12_2024_1.sql @@ -0,0 +1,26 @@ +UPDATE gepafin_schema.system_email_template +SET html_content = ' + +
+

RICHIESTA INTEGRAZIONE DOCUMENTALE

+

Buongiorno,

+

In riferimento alla domanda di concessione di Finanziamento agevolato a valere sul Fondo prestiti + {{call_name}} di cui al Protocollo n. {{protocol_number}} del + {{protocol_date}} e {{protocol_time}}, alla luce dell''attività istruttoria svolta, + segnaliamo quanto segue:

+
    +
  • {{form_dataInput}}
  • +
+

{{note}}

+

Vi invitiamo a fornire quanto sopra richiesto integrando la documentazione sia caricandola all''interno dello sportello + online {{platform_link}} che inviandola a mezzo PEC all''indirizzo + {{legal_mail}} entro e non oltre 10 giorni dal ricevimento della presente comunicazione, + precisando che, in caso di mancata ricezione nei termini indicati, saremo costretti a non prendere in considerazione la Vostra richiesta di finanziamento.

+

Vi informiamo che per la ricezione della PEC farà fede la ricevuta di avvenuta consegna che attesterà il buon esito + dell''invio. La documentazione trasmessa e le informazioni fornite saranno processate dall''istruttore assegnatario della pratica.

+

Distinti Saluti,

+

{{email_signature}}

+
+ + ' +WHERE "type" = 'DOCUMENTATION_INTEGRATION_REQUEST' AND "system" = true; \ No newline at end of file From b0b38db4c711fc0aac04ced2793173f661a97b13 Mon Sep 17 00:00:00 2001 From: rajesh Date: Wed, 4 Dec 2024 16:17:39 +0530 Subject: [PATCH 42/43] updated code --- .../dao/EmailNotificationDao.java | 97 ++++++++++++------- .../enums/RecipientTypeEnum.java | 3 +- .../db/changelog/db.changelog-1.0.0.xml | 6 ++ ...nt_mail_notification_mail_04_12_2024_1.sql | 26 +++++ 4 files changed, 95 insertions(+), 37 deletions(-) create mode 100644 src/main/resources/db/dump/update_system_email_template_for_updating_amendment_mail_notification_mail_04_12_2024_1.sql diff --git a/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java index c6a2d14b..4bf99110 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java @@ -1,23 +1,15 @@ package net.gepafin.tendermanagement.dao; import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import net.gepafin.tendermanagement.constants.GepafinConstant; import net.gepafin.tendermanagement.entities.*; -import net.gepafin.tendermanagement.enums.EmailEntityTypeEnum; import net.gepafin.tendermanagement.enums.RecipientTypeEnum; -import net.gepafin.tendermanagement.enums.StatusTypeEnum; -import net.gepafin.tendermanagement.entities.*; -import net.gepafin.tendermanagement.model.request.ApplicationAmendmentRequest; import net.gepafin.tendermanagement.model.request.EmailConfig; import net.gepafin.tendermanagement.model.request.EmailLogRequest; import net.gepafin.tendermanagement.model.response.AmendmentFormFieldResponse; import net.gepafin.tendermanagement.model.response.SystemEmailTemplateResponse; -import net.gepafin.tendermanagement.repositories.ApplicationFormFieldRepository; -import net.gepafin.tendermanagement.repositories.ApplicationFormRepository; -import net.gepafin.tendermanagement.repositories.EmailLogRepository; -import net.gepafin.tendermanagement.repositories.HubRepository; +import net.gepafin.tendermanagement.repositories.*; import net.gepafin.tendermanagement.service.*; import net.gepafin.tendermanagement.service.impl.EmailService; import net.gepafin.tendermanagement.service.impl.EmailServiceFactory; @@ -26,6 +18,7 @@ import net.gepafin.tendermanagement.util.Utils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import java.time.LocalDateTime; @@ -71,6 +64,12 @@ public class EmailNotificationDao { @Autowired private ApplicationFormFieldRepository applicationFormFieldRepository; + @Autowired + private ApplicationEvaluationRepository applicationEvaluationRepository; + + @Value("${rinaldo_email}") + private String rinaldoEmail; + private void sendEmail(ApplicationEntity applicationEntity, SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum templateType, Map bodyPlaceholders, List additionalRecipients, Long amendmentId) { @@ -86,36 +85,60 @@ public class EmailNotificationDao { // bodyPlaceholders.put("{{legal_mail}}", legalMail); String subject = Utils.replacePlaceholders(systemEmailTemplateResponse.getSubject(), subjectPlaceholders); String body = Utils.replacePlaceholders(systemEmailTemplateResponse.getHtmlContent(), bodyPlaceholders); - UserEntity userEntity = userService.validateUser(applicationEntity.getUserId()); - List recipientEmails = getRecipientEmails(applicationEntity, userEntity, additionalRecipients); - EmailLogRequest emailLogRequest = emailLogDao.createEmailLogRequest(systemEmailTemplateResponse.getEmailScenario(), RecipientTypeEnum.BENEFICIARY, 1L, - Utils.listToCommaSeparatedString(recipientEmails), userEntity.getId(), applicationEntity.getId(), amendmentId, applicationEntity.getCall().getId()); - sendMail(applicationEntity.getHubId(), subject, body, recipientEmails, emailLogRequest); + sendEmails(applicationEntity, userEntity, additionalRecipients,amendmentId,systemEmailTemplateResponse,subject,body); } - private List getRecipientEmails(ApplicationEntity applicationEntity, UserEntity userEntity, List additionalRecipients) { + private void sendEmails(ApplicationEntity applicationEntity, UserEntity userEntity, List additionalRecipients,Long amendmentId,SystemEmailTemplateResponse systemEmailTemplateResponse,String subject,String body) { - List recipientEmails = new ArrayList<>(); + Optional applicationEvaluationEntity = applicationEvaluationRepository.findByApplicationIdAndIsDeletedFalse(applicationEntity.getId()); CompanyEntity company = companyService.validateCompany(applicationEntity.getCompanyId()); - // String companyEmail = company.getEmail(); - // String contactEmail = company.getContactEmail(); - // - // if (companyEmail != null && !companyEmail.isEmpty()) { - // recipientEmails.add(companyEmail); - // } - // if (contactEmail != null && !contactEmail.isEmpty() && !contactEmail.equals(companyEmail)) { - // recipientEmails.add(contactEmail); - // } - // - // if (userEntity.getBeneficiary().getEmail() != null) { - // recipientEmails.add(userEntity.getBeneficiary().getEmail()); - // } - // if (additionalRecipients != null) { - // recipientEmails.addAll(additionalRecipients); - // } + String companyEmail = company.getEmail(); + String contactEmail = company.getContactEmail(); - recipientEmails.add("piyush1.kag1@gmail.com"); - return recipientEmails; + if (companyEmail != null && !companyEmail.isEmpty()) { + EmailLogRequest emailLogRequest = emailLogDao.createEmailLogRequest(systemEmailTemplateResponse.getEmailScenario(), RecipientTypeEnum.COMPANY,company.getId() , + companyEmail, userEntity.getId(), applicationEntity.getId(), amendmentId, applicationEntity.getCall().getId()); + sendMail(applicationEntity.getHubId(), subject, body, List.of(companyEmail), emailLogRequest); + } + if (contactEmail != null && !contactEmail.isEmpty() && !contactEmail.equals(companyEmail)) { + EmailLogRequest emailLogRequest = emailLogDao.createEmailLogRequest(systemEmailTemplateResponse.getEmailScenario(), RecipientTypeEnum.COMPANY,company.getId(), + contactEmail, userEntity.getId(), applicationEntity.getId(), amendmentId, applicationEntity.getCall().getId()); + sendMail(applicationEntity.getHubId(), subject, body, List.of(contactEmail), emailLogRequest); + } + + if (userEntity.getBeneficiary().getEmail() != null) { + String beneficiaryEmail = userEntity.getBeneficiary().getEmail(); + EmailLogRequest emailLogRequest = emailLogDao.createEmailLogRequest(systemEmailTemplateResponse.getEmailScenario(), RecipientTypeEnum.BENEFICIARY,userEntity.getBeneficiary().getId() , + beneficiaryEmail, userEntity.getId(), applicationEntity.getId(), amendmentId, applicationEntity.getCall().getId()); + sendMail(applicationEntity.getHubId(), subject, body, List.of(beneficiaryEmail), emailLogRequest); + } + if(userEntity.getHub().getEmail() != null){ + String hubEmails = userEntity.getHub().getEmail(); + String[] hubEmailArray = hubEmails.split(","); + for (String hubEmail : hubEmailArray) { + hubEmail = hubEmail.trim(); + if (!hubEmail.isEmpty()) { + EmailLogRequest emailLogRequest = emailLogDao.createEmailLogRequest(systemEmailTemplateResponse.getEmailScenario(), RecipientTypeEnum.PROPERTIES,null, + hubEmail, userEntity.getId(), applicationEntity.getId(), amendmentId, applicationEntity.getCall().getId()); + sendMail(applicationEntity.getHubId(), subject, body, List.of(hubEmail), emailLogRequest); + } + } + } + if (rinaldoEmail != null) { + EmailLogRequest emailLogRequest = emailLogDao.createEmailLogRequest(systemEmailTemplateResponse.getEmailScenario(), RecipientTypeEnum.PROPERTIES,null , + rinaldoEmail, userEntity.getId(), applicationEntity.getId(), amendmentId, applicationEntity.getCall().getId()); + sendMail(applicationEntity.getHubId(), subject, body, List.of(rinaldoEmail), emailLogRequest); + } + if (applicationEvaluationEntity.isPresent()) { + Long preInstructorId = applicationEvaluationEntity.get().getUserId(); // Assuming UserEntity has an email field + UserEntity instructorUser = userService.validateUser(preInstructorId); + String preInstructorEmail = instructorUser.getEmail(); + if (preInstructorEmail != null && !preInstructorEmail.isEmpty()) { + EmailLogRequest emailLogRequest = emailLogDao.createEmailLogRequest(systemEmailTemplateResponse.getEmailScenario(), RecipientTypeEnum.INSTRUCTOR, instructorUser.getId(), + preInstructorEmail, userEntity.getId(), applicationEntity.getId(), amendmentId, applicationEntity.getCall().getId()); + sendMail(applicationEntity.getHubId(), subject, body, List.of(preInstructorEmail), emailLogRequest); + } + } } // // private String determineService(Long hubId) { @@ -132,6 +155,7 @@ public class EmailNotificationDao { bodyPlaceholders.put("{{protocol_number}}", applicationAmendmentRequestEntity.getProtocol().getProtocolNumber().toString()); bodyPlaceholders.put("{{protocol_date}}", DateTimeUtil.formatLocalDateTime(applicationAmendmentRequestEntity.getProtocol().getCreatedDate(), GepafinConstant.DD_MM_YYYY)); bodyPlaceholders.put("{{protocol_time}}", DateTimeUtil.parseLocalTimeToString(applicationAmendmentRequestEntity.getProtocol().getTime(), GepafinConstant.HH_MM_SS)); + bodyPlaceholders.put("{{response_days}}", applicationAmendmentRequestEntity.getResponseDays().toString()); try { // Retrieve forms and initialize required collections @@ -149,8 +173,9 @@ public class EmailNotificationDao { // Process allFormFields and generate bullet points for (AmendmentFormFieldResponse field : allFormFields) { // Build bullet points - bulletPoints.append(field.getLabel()); - bulletPoints.append("\n"); +// bulletPoints.append(field.getLabel()); + bulletPoints.append("
  • ").append(field.getLabel()).append("
  • "); + } // Add the generated bullet points to placeholders bodyPlaceholders.put("{{form_dataInput}}", bulletPoints.toString()); diff --git a/src/main/java/net/gepafin/tendermanagement/enums/RecipientTypeEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/RecipientTypeEnum.java index c4f54175..8f656154 100644 --- a/src/main/java/net/gepafin/tendermanagement/enums/RecipientTypeEnum.java +++ b/src/main/java/net/gepafin/tendermanagement/enums/RecipientTypeEnum.java @@ -7,7 +7,8 @@ public enum RecipientTypeEnum { BENEFICIARY ("BENEFICIARY"), USER("USER"), COMPANY("COMPANY"), - PROPERTIES("PROPERTIES"); + PROPERTIES("PROPERTIES"), + INSTRUCTOR("INSTRUCTOR"); private String value; 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 61d8101f..9c061c37 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 @@ -1967,4 +1967,10 @@ path="db/dump/update_system_email_template_for_updating_amendment_mail_notification_mail_03_12_2024_1.sql"/> + + + + + diff --git a/src/main/resources/db/dump/update_system_email_template_for_updating_amendment_mail_notification_mail_04_12_2024_1.sql b/src/main/resources/db/dump/update_system_email_template_for_updating_amendment_mail_notification_mail_04_12_2024_1.sql new file mode 100644 index 00000000..564d855d --- /dev/null +++ b/src/main/resources/db/dump/update_system_email_template_for_updating_amendment_mail_notification_mail_04_12_2024_1.sql @@ -0,0 +1,26 @@ +UPDATE gepafin_schema.system_email_template +SET html_content = ' + +
    +

    RICHIESTA INTEGRAZIONE DOCUMENTALE

    +

    Buongiorno,

    +

    In riferimento alla domanda di concessione di Finanziamento agevolato a valere sul Fondo prestiti + {{call_name}} di cui al Protocollo n. {{protocol_number}} del + {{protocol_date}} e {{protocol_time}}, alla luce dell''attività istruttoria svolta, + segnaliamo quanto segue:

    +
      +
    • {{form_dataInput}}
    • +
    +

    {{note}}

    +

    Vi invitiamo a fornire quanto sopra richiesto integrando la documentazione sia caricandola all''interno dello sportello + online {{platform_link}} che inviandola a mezzo PEC all''indirizzo + bandi.gepafin@legalmail.it entro e non oltre {{response_days}} giorni dal ricevimento della presente comunicazione, + precisando che, in caso di mancata ricezione nei termini indicati, saremo costretti a non prendere in considerazione la Vostra richiesta di finanziamento.

    +

    Vi informiamo che per la ricezione della PEC farà fede la ricevuta di avvenuta consegna che attesterà il buon esito + dell''invio. La documentazione trasmessa e le informazioni fornite saranno processate dall''istruttore assegnatario della pratica.

    +

    Distinti Saluti,

    +

    {{email_signature}}

    +
    + + ' +WHERE "type" = 'DOCUMENTATION_INTEGRATION_REQUEST' AND "system" = true; \ No newline at end of file From 60af8819246275d104acdef4f32e72ab8237e364 Mon Sep 17 00:00:00 2001 From: rajeshkhore Date: Wed, 4 Dec 2024 20:45:42 +0530 Subject: [PATCH 43/43] FIxed JWT issue --- .../config/jwt/JWTFilter.java | 69 ++++++------ .../config/jwt/TokenProvider.java | 100 ++++++++---------- .../service/impl/AuthenticationService.java | 2 - src/main/resources/application.properties | 4 +- 4 files changed, 85 insertions(+), 90 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/config/jwt/JWTFilter.java b/src/main/java/net/gepafin/tendermanagement/config/jwt/JWTFilter.java index 4d8d5948..8f8f3131 100644 --- a/src/main/java/net/gepafin/tendermanagement/config/jwt/JWTFilter.java +++ b/src/main/java/net/gepafin/tendermanagement/config/jwt/JWTFilter.java @@ -1,43 +1,48 @@ package net.gepafin.tendermanagement.config.jwt; -import jakarta.servlet.FilterChain; -import jakarta.servlet.ServletException; -import jakarta.servlet.ServletRequest; -import jakarta.servlet.ServletResponse; -import jakarta.servlet.http.HttpServletRequest; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.util.StringUtils; -import org.springframework.web.filter.GenericFilterBean; - import java.io.IOException; -public class JWTFilter extends GenericFilterBean { +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.util.StringUtils; +import org.springframework.web.filter.OncePerRequestFilter; - private final TokenProvider tokenProvider; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; - public JWTFilter(TokenProvider tokenProvider) { - this.tokenProvider = tokenProvider; - } +public class JWTFilter extends OncePerRequestFilter { - @Override - public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) - throws IOException, ServletException { - HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest; - String token = resolveToken(httpServletRequest); + private final TokenProvider tokenProvider; - if (StringUtils.hasText(token) && tokenProvider.validateToken(token)) { - Authentication authentication = tokenProvider.getAuthentication(token); - if (authentication != null) { - SecurityContextHolder.getContext().setAuthentication(authentication); - } - } + public JWTFilter(TokenProvider tokenProvider) { + this.tokenProvider = tokenProvider; + } - filterChain.doFilter(servletRequest, servletResponse); - } + protected void doFilterInternal(HttpServletRequest servletRequest, HttpServletResponse servletResponse, + FilterChain filterChain) throws ServletException, IOException { - private String resolveToken(HttpServletRequest request) { - String bearerToken = request.getHeader("Authorization"); - return StringUtils.hasText(bearerToken) && bearerToken.startsWith("Bearer ") ? bearerToken.substring(7) : null; - } + try { + HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest; + String token = resolveToken(httpServletRequest); + + if (StringUtils.hasText(token) && tokenProvider.validateToken(token)) { + Authentication authentication = tokenProvider.getAuthentication(token); + if (authentication != null) { + SecurityContextHolder.getContext().setAuthentication(authentication); + } + } + + filterChain.doFilter(servletRequest, servletResponse); + } catch (Exception e) { + servletResponse.setStatus(HttpServletResponse.SC_FORBIDDEN); + } + + } + + private String resolveToken(HttpServletRequest request) { + String bearerToken = request.getHeader("Authorization"); + return StringUtils.hasText(bearerToken) && bearerToken.startsWith("Bearer ") ? bearerToken.substring(7) : null; + } } diff --git a/src/main/java/net/gepafin/tendermanagement/config/jwt/TokenProvider.java b/src/main/java/net/gepafin/tendermanagement/config/jwt/TokenProvider.java index 41d9fc16..fa4ad277 100644 --- a/src/main/java/net/gepafin/tendermanagement/config/jwt/TokenProvider.java +++ b/src/main/java/net/gepafin/tendermanagement/config/jwt/TokenProvider.java @@ -1,5 +1,39 @@ package net.gepafin.tendermanagement.config.jwt; +import static io.micrometer.common.util.StringUtils.isEmpty; + +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.Base64; +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +import javax.crypto.SecretKey; + +import org.apache.commons.lang3.ArrayUtils; +import org.apache.commons.lang3.time.DateUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.User; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; + +import com.google.gson.Gson; + import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; @@ -14,30 +48,6 @@ import net.gepafin.tendermanagement.repositories.UserRepository; import net.gepafin.tendermanagement.util.Utils; import net.gepafin.tendermanagement.web.rest.api.errors.Status; import net.gepafin.tendermanagement.web.rest.api.errors.UnauthorizedAccessException; -import org.apache.commons.lang3.ArrayUtils; -import org.apache.commons.lang3.time.DateUtils; -import org.apache.http.HttpResponse; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.core.authority.SimpleGrantedAuthority; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.security.core.userdetails.User; -import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.stereotype.Component; -import org.springframework.util.StringUtils; - -import javax.crypto.SecretKey; -import java.nio.charset.StandardCharsets; -import java.util.*; -import java.util.stream.Collectors; -import com.google.gson.Gson; - -import static io.micrometer.common.util.StringUtils.isEmpty; @Component @@ -48,7 +58,7 @@ public class TokenProvider { private String secretKey; @Value("${security.authentication.jwt.token-validity-in-seconds}") - private long tokenValidityInSeconds; + private int tokenValidityInSeconds; @Autowired private UserRepository userRepository; @@ -60,7 +70,6 @@ public class TokenProvider { private static final String MERCHANTID="merchantId"; static final String AUTH_SECRET = "X-Api-Secret"; - private final Set invalidatedTokens = new HashSet<>(); private static final String USER_ID = "userId"; public UserEntity validateUser(Map userInfo) { @@ -96,12 +105,12 @@ public class TokenProvider { Date validity; if (Boolean.TRUE.equals(rememberMe)) { - now = DateUtils.addMonths(new Date(), 2).getTime(); + now = DateUtils.addDays(new Date(), 2).getTime(); validity = new Date(now); - log.info("Creating token with extended validity for 2 months."); + log.info("Creating token with extended validity for 2 days."); } else { - now = (new Date()).getTime(); - validity = new Date(now + (this.tokenValidityInSeconds * 1000)); + now = DateUtils.addSeconds(new Date(), this.tokenValidityInSeconds).getTime(); + validity = new Date(now); log.info("Creating token with standard validity of {} seconds.", this.tokenValidityInSeconds); } @@ -148,32 +157,15 @@ public class TokenProvider { return authorities; } - public boolean validateToken(String authToken) { - try { - if (isTokenInvalid(authToken)) { - log.warn("Token is invalidated."); - return false; - } - Jwts.parserBuilder() - .setSigningKey(key) - .build() - .parseClaimsJws(authToken); - log.info("Token is valid."); - return true; - } catch (Exception e) { - log.error("Token validation failed: {}", e.getMessage()); - return false; - } - } + public boolean validateToken(String authToken) { - public void invalidateToken(String token) { - invalidatedTokens.add(token); - log.info("Token invalidated: {}", token); - } + Jwts.parserBuilder().setSigningKey(key).build().parseClaimsJws(authToken); + log.info("Token is valid."); + return true; - public boolean isTokenInvalid(String token) { - return invalidatedTokens.contains(token); - } + } + + public Map getUserInfoAndUserIdFromToken(HttpServletRequest request) { Map userInfo = new HashMap<>(); String authSecretHeader=request.getHeader(AUTH_SECRET); diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/AuthenticationService.java b/src/main/java/net/gepafin/tendermanagement/service/impl/AuthenticationService.java index d4dab052..ad8182de 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/AuthenticationService.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/AuthenticationService.java @@ -203,8 +203,6 @@ public class AuthenticationService { public void logout(HttpServletRequest request, HttpServletResponse response) { Authentication auth = SecurityContextHolder.getContext().getAuthentication(); if (auth != null) { - String token = tokenProvider.extractTokenFromRequest(request); - tokenProvider.invalidateToken(token); new SecurityContextLogoutHandler().logout(request, response, auth); } SecurityContextHolder.getContext().setAuthentication(null); diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 19988cf3..fb109ba7 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -37,8 +37,8 @@ aws.s3.url = https://mementoresources.s3.eu-west-1.amazonaws.com/ #aws.s3.url.folder.signed.document=gepafin/signed-document # JWT configuration # Ensure these values match your expectations -security.authentication.jwt.secret=my-secret-token-to-change-in-prod-environment-your-super-secure-randomly-generated-key -security.authentication.jwt.token-validity-in-seconds=86400 +security.authentication.jwt.secret=Z3/zjSD96Hdvh/AMyaMLJLWSVF00AOmxxEk4Kv8E+bM3bUW/QXOu45OSgRD6H16RvQ/pWZznDQP3l2ZkPlu9Sg== +security.authentication.jwt.token-validity-in-seconds=7200 # Default system base URLs base-url=https://api-dev-gepafin.memento.credit