diff --git a/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java b/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java index bef8c76f..8ca802c6 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java @@ -15,6 +15,10 @@ import java.util.stream.Collectors; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; +import jakarta.persistence.criteria.CriteriaBuilder; +import jakarta.persistence.criteria.Expression; +import jakarta.persistence.criteria.Predicate; +import jakarta.persistence.criteria.Root; import jakarta.persistence.criteria.*; import jakarta.servlet.http.HttpServletRequest; import net.gepafin.tendermanagement.entities.*; @@ -805,6 +809,30 @@ public class CallDao { } else { calls = callRepository.findByStatusInAndHubId(callStatusList, user.getHub().getId()); } + LocalDateTime now = LocalDateTime.now(); + for (CallEntity call : calls) { + CallEntity oldCallEntity = Utils.getClonedEntityForData(call); + if (CallStatusEnum.PUBLISH.getValue().equals(call.getStatus()) && + call.getEndDate() != null && call.getEndTime() != null) { + LocalDateTime callEndDateTime = LocalDateTime.of(LocalDate.from(call.getEndDate()), call.getEndTime()); + if (callEndDateTime.isBefore(now)) { + call.setStatus(CallStatusEnum.EXPIRED.getValue()); + callRepository.save(call); + } + if (Boolean.FALSE.equals(oldCallEntity.getStatus().equals(call.getStatus()))) { + + loggingUtil.logUserAction(UserActionRequest.builder() + .request(request) + .actionType(UserActionLogsEnum.UPDATE) + .actionContext(UserActionContextEnum.UPDATE_EXPIRED_CALL) + .build()); + + /** This code is responsible for adding a version history log for the "update call status to EXPIRED" operation **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldCallEntity).newData(call).build()); + } + } + } + List callIds = calls.stream().map(CallEntity::getId).collect(Collectors.toList()); Map preferredCallsMap = getBeneficiaryPreferredCallsForUser(request,user, callIds, companyId); @@ -981,7 +1009,7 @@ public class CallDao { Translator.toLocale(GepafinConstant.COMPANY_ID_REQUIRED_FOR_PREFERRED_CALL) ); } - Specification spec = search(user, callPageableRequestBean); + Specification spec = search(request,user, callPageableRequestBean); Page entityPage; if (Boolean.TRUE.equals(onlyPreferredCall)) { validator.validateUserWithCompany(request, companyId); @@ -1028,10 +1056,10 @@ public class CallDao { return pageableResponseBean; } - public Specification search(UserEntity userEntity, CallPageableRequestBean callPageableRequestBean) { + public Specification search(HttpServletRequest request,UserEntity userEntity, CallPageableRequestBean callPageableRequestBean) { return (root, query, criteriaBuilder) -> { - List predicates = getPredicates(callPageableRequestBean, criteriaBuilder, root, userEntity); + List predicates = getPredicates(request,callPageableRequestBean, criteriaBuilder, root, userEntity); SortBy sortBy = new SortBy(GepafinConstant.CREATED_DATE, true); if (callPageableRequestBean.getGlobalFilters() != null @@ -1054,9 +1082,9 @@ public class CallDao { } - private List getPredicates(CallPageableRequestBean callPageableRequestBean, + private List getPredicates(HttpServletRequest request,CallPageableRequestBean callPageableRequestBean, CriteriaBuilder criteriaBuilder, Root root, UserEntity userEntity) { - + expirePublishedCalls(request); Integer year = null; String search = null; Map filters = new HashMap<>(); @@ -1112,11 +1140,59 @@ public class CallDao { applyFilters(root, criteriaBuilder, predicates, filters); predicates.add(criteriaBuilder.equal(root.get(GepafinConstant.HUB).get(GepafinConstant.ID), userEntity.getHub().getId())); - return predicates; } + public void expirePublishedCalls(HttpServletRequest request) { + List expiredCalls = callRepository.findAll((root, query, criteriaBuilder) -> { + Predicate isPublished = criteriaBuilder.equal(root.get(GepafinConstant.STATUS), CallStatusEnum.PUBLISH.name()); + + // Concatenate date and time as a single string + Expression dateTimeString = criteriaBuilder.concat( + root.get(GepafinConstant.END_DATE), + criteriaBuilder.literal(" ") // Space between date and time + ); + Expression fullDateTimeString = criteriaBuilder.concat(dateTimeString, root.get(GepafinConstant.END_TIME)); + + // Convert the concatenated string into TIMESTAMP + Expression endDateTime = criteriaBuilder.function( + "to_timestamp", + LocalDateTime.class, + fullDateTimeString, + criteriaBuilder.literal("YYYY-MM-DD HH24:MI:SS") + ); + + Predicate isExpired = criteriaBuilder.lessThan(endDateTime, LocalDateTime.now()); + + return criteriaBuilder.and(isPublished, isExpired); + }); + + if (!expiredCalls.isEmpty()) { + for (CallEntity call : expiredCalls) { + CallEntity oldCallEntity = Utils.getClonedEntityForData(call); // Clone before modification + call.setStatus(CallStatusEnum.EXPIRED.getValue()); + + if (!oldCallEntity.getStatus().equals(call.getStatus())) { + // Log user action + loggingUtil.logUserAction(UserActionRequest.builder() + .request(request) + .actionType(UserActionLogsEnum.UPDATE) + .actionContext(UserActionContextEnum.UPDATE_EXPIRED_CALL) + .build()); + + // Add version history log + loggingUtil.addVersionHistory(VersionHistoryRequest.builder() + .request(request) + .actionType(VersionActionTypeEnum.UPDATE) + .oldData(oldCallEntity) + .newData(call) + .build()); + } + } + callRepository.saveAll(expiredCalls); // Save all modified calls at once + } + } private void applyFilters(Root root, CriteriaBuilder criteriaBuilder, List predicates, Map filters) { if (Boolean.FALSE.equals(filters.isEmpty())) { for (Map.Entry entry : filters.entrySet()) { diff --git a/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java index c1d0d83e..766ffc1d 100644 --- a/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java +++ b/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java @@ -213,7 +213,8 @@ public enum UserActionContextEnum { GET_ALL_APPLICATION_AMENDMENT_BY_PAGINATION("GET_ALL_APPLICATION_AMENDMENT_BY_PAGINATION"), GET_ALL_USER_ACTION_BY_PAGINATION("GET_ALL_USER_ACTION_BY_PAGINATION"), GET_ALL_USER_BY_PAGINATION("GET_ALL_USER_BY_PAGINATION"), - UPDATE_CALL_END_DATE_AND_TIME("UPDATE_CALL_END_DATE_AND_TIME"); + UPDATE_CALL_END_DATE_AND_TIME("UPDATE_CALL_END_DATE_AND_TIME"), + UPDATE_EXPIRED_CALL("UPDATE_EXPIRED_CALL") ; private final String value; diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/CallServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/CallServiceImpl.java index c5b6952b..3eaed63d 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/CallServiceImpl.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/CallServiceImpl.java @@ -61,7 +61,7 @@ public class CallServiceImpl implements CallService { } @Override - @Transactional(readOnly = true) + @Transactional(rollbackFor = Exception.class) public List getAllCalls(HttpServletRequest request,Long companyId,Boolean onlyPreferredCall) { UserEntity user = validator.validateUser(request); return callDao.getAllCalls(request,user,companyId,onlyPreferredCall); @@ -104,6 +104,7 @@ public class CallServiceImpl implements CallService { } @Override + @Transactional(rollbackFor = Exception.class) public PageableResponseBean> getAllCallsByPagination(HttpServletRequest request,Long companyId , Boolean onlyPreferredCall, CallPageableRequestBean callPageableRequestBean) { UserEntity user = validator.validateUser(request); return callDao.getAllCallsByPagination(request,user,companyId,onlyPreferredCall,callPageableRequestBean);