From 2c01cbc39a4d791b5da6b74e39f978244ed2b759 Mon Sep 17 00:00:00 2001 From: nisha Date: Thu, 23 Jan 2025 14:11:58 +0530 Subject: [PATCH] Done ticket GEPAFINBE-144 --- .../tendermanagement/dao/DashboardDao.java | 75 +++++++++++++++---- .../enums/UserActionContextEnum.java | 1 + ...AssignedApplicationWidgetResponseBean.java | 15 ++++ .../ApplicationEvaluationRepository.java | 4 +- .../AssignedApplicationsRepository.java | 40 ++++++++++ .../service/DashboardService.java | 3 + .../service/impl/DashboardServiceImpl.java | 7 ++ .../web/rest/api/DashboardApi.java | 16 ++++ .../rest/api/impl/DashboardApiController.java | 14 ++++ 9 files changed, 158 insertions(+), 17 deletions(-) create mode 100644 src/main/java/net/gepafin/tendermanagement/model/response/AssignedApplicationWidgetResponseBean.java diff --git a/src/main/java/net/gepafin/tendermanagement/dao/DashboardDao.java b/src/main/java/net/gepafin/tendermanagement/dao/DashboardDao.java index 1f17ef3e..4dbca0cf 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/DashboardDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/DashboardDao.java @@ -6,31 +6,23 @@ import net.gepafin.tendermanagement.entities.UserActionEntity; import net.gepafin.tendermanagement.entities.UserEntity; import net.gepafin.tendermanagement.entities.UserWithCompanyEntity; import net.gepafin.tendermanagement.entities.*; -import net.gepafin.tendermanagement.enums.ApplicationAmendmentRequestEnum; -import net.gepafin.tendermanagement.enums.CallStatusEnum; -import net.gepafin.tendermanagement.enums.RoleStatusEnum; -import net.gepafin.tendermanagement.enums.UserStatusEnum; +import net.gepafin.tendermanagement.enums.*; import net.gepafin.tendermanagement.model.response.*; import net.gepafin.tendermanagement.repositories.*; import net.gepafin.tendermanagement.service.CompanyService; import net.gepafin.tendermanagement.util.Validator; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageRequest; -import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Component; import java.math.BigDecimal; import java.math.RoundingMode; -import java.time.temporal.ChronoUnit; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.*; import java.time.LocalDate; import java.time.LocalDateTime; -import java.time.LocalTime; -import java.util.List; -import java.util.List; + import java.util.stream.Collectors; @Component @@ -57,8 +49,6 @@ public class DashboardDao { @Autowired private ApplicationEvaluationRepository applicationEvaluationRepository; - @Autowired - private UserActionsRepository userActionsRepository; @Autowired private ApplicationAmendmentRequestRepository applicationAmendmentRequestRepository; @@ -258,14 +248,15 @@ public class DashboardDao { if (Boolean.FALSE.equals(applicationIds.isEmpty())) { BigDecimal averageTime = applicationEvaluationRepository.findAverageEvaluationTimeByApplicationIds(applicationIds); - responseBean.setEvaluationAverageTime(averageTime != null ? averageTime : BigDecimal.ZERO); + responseBean.setEvaluationAverageTime(averageTime != null ? averageTime.setScale(2, RoundingMode.HALF_UP) : BigDecimal.ZERO); } LocalDate twoDaysLater = LocalDate.now().plusDays(2); - + List statusList =Arrays.asList( ApplicationEvaluationStatusTypeEnum.OPEN.getValue(), ApplicationEvaluationStatusTypeEnum.SOCCORSO.getValue()); Long dueApplications = applicationEvaluationRepository.countDueApplicationsBetween( applicationIds, LocalDate.now(), - twoDaysLater + twoDaysLater, + statusList ); if (dueApplications != null) { @@ -362,5 +353,57 @@ public class DashboardDao { } } + public AssignedApplicationWidgetResponseBean getApplicationDetailsForEvaluation(UserEntity userEntity) { + Long userId = userEntity.getId(); + Long hubId = userEntity.getHub().getId(); + + Object[] results; + List applicationIds; + if (validator.checkIsPreInstructor()) { + results = assignedApplicationsRepository.countAssignedApplicationsWithStatus(userId, hubId); + applicationIds = assignedApplicationsRepository.findApplicationIdsByUserIdAndHubIdAndIsDeletedFalse(userId,hubId); + } else { + results = assignedApplicationsRepository.countAssignedApplicationsForHub(hubId); + applicationIds = assignedApplicationsRepository.findApplicationIdsByHubId(hubId); + } + AssignedApplicationWidgetResponseBean response = convertToResponse(results); + calculateEvaluationAvgTimeForAssignedApplication(response, applicationIds); + return response; + } + + private void calculateEvaluationAvgTimeForAssignedApplication(AssignedApplicationWidgetResponseBean response, List applicationIds) { + if (applicationIds == null || applicationIds.isEmpty()) { + response.setEvaluationAverageTime(BigDecimal.ZERO); + response.setNumberOfApplicationExpiringIn48Hours(0L); + return; + } + + BigDecimal averageTime = applicationEvaluationRepository.findAverageEvaluationTimeByApplicationIds(applicationIds); + response.setEvaluationAverageTime(averageTime != null ? averageTime.setScale(2, RoundingMode.HALF_UP) : BigDecimal.ZERO); + + LocalDate today = LocalDate.now(); + LocalDate twoDaysLater = today.plusDays(2); + List statusList =Arrays.asList( ApplicationEvaluationStatusTypeEnum.OPEN.getValue(), ApplicationEvaluationStatusTypeEnum.SOCCORSO.getValue()); + Long dueApplications = applicationEvaluationRepository.countDueApplicationsBetween( + applicationIds, today, twoDaysLater,statusList + ); + response.setNumberOfApplicationExpiringIn48Hours(dueApplications != null ? dueApplications : 0L); + } + + private AssignedApplicationWidgetResponseBean convertToResponse(Object[] results) { + AssignedApplicationWidgetResponseBean response = new AssignedApplicationWidgetResponseBean(); + + Object[] data = (Object[]) results[0]; + + response.setNumberOfAssignedApplication(data[0] instanceof Number ? ((Number) data[0]).longValue() : 0L); + response.setNumberOfApplicationInAmendmentState(data[1] instanceof Number ? ((Number) data[1]).longValue() : 0L); + response.setNumberOfApplicationInEvaluationState(data[2] instanceof Number ? ((Number) data[2]).longValue() : 0L); + response.setNumberOfAcceptedApplication(data[3] instanceof Number ? ((Number) data[3]).longValue() : 0L); + + 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 64fd530c..503f0383 100644 --- a/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java +++ b/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java @@ -138,6 +138,7 @@ public enum UserActionContextEnum { GET_DASHBOARD_WIDGET_FOR_BENEFICIARY("GET_DASHBOARD_WIDGET_FOR_BENEFICIARY"), GET_APPLICATION_DETAILS("GET_APPLICATION_DETAILS"), GET_AMENDMENT_DETAILS("GET_AMENDMENT_DETAILS"), + GET_APPLICATION_DETAILS_FOR_EVALUATION("GET_APPLICATION_DETAILS_FOR_EVALUATION"), /** Evaluation criteria action context **/ GET_EVALUATION_CRITERIA("GET_EVALUATION_CRITERIA"), diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/AssignedApplicationWidgetResponseBean.java b/src/main/java/net/gepafin/tendermanagement/model/response/AssignedApplicationWidgetResponseBean.java new file mode 100644 index 00000000..163acdad --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/model/response/AssignedApplicationWidgetResponseBean.java @@ -0,0 +1,15 @@ +package net.gepafin.tendermanagement.model.response; + +import lombok.Data; + +import java.math.BigDecimal; + +@Data +public class AssignedApplicationWidgetResponseBean { + private Long numberOfAssignedApplication; + private Long numberOfApplicationInAmendmentState; + private Long numberOfAcceptedApplication; + private Long numberOfApplicationInEvaluationState; + private Long numberOfApplicationExpiringIn48Hours; + private BigDecimal evaluationAverageTime; +} diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationEvaluationRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationEvaluationRepository.java index cf0b9c66..468a5a6f 100644 --- a/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationEvaluationRepository.java +++ b/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationEvaluationRepository.java @@ -55,11 +55,13 @@ public interface ApplicationEvaluationRepository extends JpaRepository applicationIds, @Param("startDate") LocalDate startDate, - @Param("endDate") LocalDate endDate + @Param("endDate") LocalDate endDate, + @Param("statusList") List statusList ); diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/AssignedApplicationsRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/AssignedApplicationsRepository.java index 56036759..16fa4928 100644 --- a/src/main/java/net/gepafin/tendermanagement/repositories/AssignedApplicationsRepository.java +++ b/src/main/java/net/gepafin/tendermanagement/repositories/AssignedApplicationsRepository.java @@ -25,4 +25,44 @@ public interface AssignedApplicationsRepository extends JpaRepository findApplicationIdsByUserIdAndIsDeletedFalse(@Param("userId") Long userId); + + @Query(""" + SELECT + COALESCE(COUNT(a.id), 0) AS totalAssigned, + COALESCE(SUM(CASE WHEN app.status = 'SOCCORSO' THEN 1 ELSE 0 END), 0) AS amendmentCount, + COALESCE(SUM(CASE WHEN app.status = 'EVALUATION' THEN 1 ELSE 0 END), 0) AS evaluationCount, + COALESCE(SUM(CASE WHEN app.status = 'APPROVED' THEN 1 ELSE 0 END), 0) AS approvedCount + FROM AssignedApplicationsEntity a + JOIN a.application app + WHERE a.isDeleted = false + AND a.userId = :userId + AND app.hubId = :hubId +""") + Object[] countAssignedApplicationsWithStatus( + @Param("userId") Long userId, + @Param("hubId") Long hubId + ); + + @Query(""" + SELECT + COALESCE(COUNT(a.id), 0) AS totalAssigned, + COALESCE(SUM(CASE WHEN app.status = 'SOCCORSO' THEN 1 ELSE 0 END), 0) AS amendmentCount, + COALESCE(SUM(CASE WHEN app.status = 'EVALUATION' THEN 1 ELSE 0 END), 0) AS evaluationCount, + COALESCE(SUM(CASE WHEN app.status = 'APPROVED' THEN 1 ELSE 0 END), 0) AS approvedCount + FROM AssignedApplicationsEntity a + JOIN a.application app + WHERE a.isDeleted = false + AND app.hubId = :hubId +""") + Object[] countAssignedApplicationsForHub(@Param("hubId") Long hubId); + + @Query("SELECT aa.application.id FROM AssignedApplicationsEntity aa " + + "WHERE aa.userId = :userId AND aa.application.hubId = :hubId AND aa.isDeleted = false") + List findApplicationIdsByUserIdAndHubIdAndIsDeletedFalse(@Param("userId") Long userId, @Param("hubId") Long hubId); + + @Query("SELECT aa.application.id FROM AssignedApplicationsEntity aa " + + "WHERE aa.application.hubId = :hubId AND aa.isDeleted = false") + List findApplicationIdsByHubId(@Param("hubId") Long hubId); + + } diff --git a/src/main/java/net/gepafin/tendermanagement/service/DashboardService.java b/src/main/java/net/gepafin/tendermanagement/service/DashboardService.java index ee7429d4..f2076f0c 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/DashboardService.java +++ b/src/main/java/net/gepafin/tendermanagement/service/DashboardService.java @@ -3,6 +3,7 @@ package net.gepafin.tendermanagement.service; import jakarta.servlet.http.HttpServletRequest; import net.gepafin.tendermanagement.model.response.AmendmentWidgetResponseBean; import net.gepafin.tendermanagement.model.response.ApplicationWidgetResponseBean; +import net.gepafin.tendermanagement.model.response.AssignedApplicationWidgetResponseBean; import net.gepafin.tendermanagement.model.response.BeneficiaryWidgetResponseBean; import net.gepafin.tendermanagement.model.response.SuperAdminWidgetResponseBean; @@ -13,4 +14,6 @@ public interface DashboardService { public BeneficiaryWidgetResponseBean getDashboardWidgetForBeneficiary(HttpServletRequest request, Long companyId); public ApplicationWidgetResponseBean getApplicationDetails(HttpServletRequest request); public AmendmentWidgetResponseBean getAmendmentDetails(HttpServletRequest request); + public AssignedApplicationWidgetResponseBean getApplicationDetailsForEvaluation(HttpServletRequest request); + } diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/DashboardServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/DashboardServiceImpl.java index e157d293..a3cf0482 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/DashboardServiceImpl.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/DashboardServiceImpl.java @@ -6,6 +6,7 @@ import net.gepafin.tendermanagement.entities.CompanyEntity; import net.gepafin.tendermanagement.entities.UserEntity; import net.gepafin.tendermanagement.model.response.AmendmentWidgetResponseBean; import net.gepafin.tendermanagement.model.response.ApplicationWidgetResponseBean; +import net.gepafin.tendermanagement.model.response.AssignedApplicationWidgetResponseBean; import net.gepafin.tendermanagement.model.response.BeneficiaryWidgetResponseBean; import net.gepafin.tendermanagement.model.response.SuperAdminWidgetResponseBean; import net.gepafin.tendermanagement.service.DashboardService; @@ -45,4 +46,10 @@ public class DashboardServiceImpl implements DashboardService { UserEntity userEntity=validator.validateUser(request); return dashboardDao.getAmendmentDetails(userEntity); } + + @Override + public AssignedApplicationWidgetResponseBean getApplicationDetailsForEvaluation(HttpServletRequest request) { + UserEntity userEntity = validator.validateUser(request); + return dashboardDao.getApplicationDetailsForEvaluation(userEntity); + } } diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/DashboardApi.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/DashboardApi.java index bf1779fc..2fe77d1b 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/DashboardApi.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/DashboardApi.java @@ -8,6 +8,7 @@ import io.swagger.v3.oas.annotations.responses.ApiResponse; import jakarta.servlet.http.HttpServletRequest; import net.gepafin.tendermanagement.model.response.AmendmentWidgetResponseBean; import net.gepafin.tendermanagement.model.response.ApplicationWidgetResponseBean; +import net.gepafin.tendermanagement.model.response.AssignedApplicationWidgetResponseBean; import net.gepafin.tendermanagement.model.response.BeneficiaryWidgetResponseBean; import net.gepafin.tendermanagement.model.response.SuperAdminWidgetResponseBean; import net.gepafin.tendermanagement.model.util.Response; @@ -75,4 +76,19 @@ public interface DashboardApi { produces = { "application/json" }) @PreAuthorize("hasRole('ROLE_SUPER_ADMIN') || hasRole('ROLE_INSTRUCTOR_MANAGER')|| hasRole('ROLE_PRE_INSTRUCTOR')") ResponseEntity> getAmendmentDetails(HttpServletRequest request); + + @Operation(summary = "Api to get Application details for Evaluation", + responses = { + @ApiResponse(responseCode = "200", description = "OK"), + @ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.NOTFOUND_ERROR_EXAMPLE) })), + @ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.UNAUTHORIZED_ERROR_EXAMPLE) })), + @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) }) + @GetMapping(value = "/evaluation", + produces = { "application/json" }) + @PreAuthorize("hasRole('ROLE_SUPER_ADMIN') || hasRole('ROLE_INSTRUCTOR_MANAGER')|| hasRole('ROLE_PRE_INSTRUCTOR')") + ResponseEntity> getApplicationDetailsForEvaluation(HttpServletRequest request); + } 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 c9bc0d85..7a4a489c 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 @@ -8,6 +8,7 @@ import net.gepafin.tendermanagement.enums.UserActionLogsEnum; import net.gepafin.tendermanagement.model.request.UserActionRequest; import net.gepafin.tendermanagement.model.response.AmendmentWidgetResponseBean; import net.gepafin.tendermanagement.model.response.ApplicationWidgetResponseBean; +import net.gepafin.tendermanagement.model.response.AssignedApplicationWidgetResponseBean; import net.gepafin.tendermanagement.model.response.BeneficiaryWidgetResponseBean; import net.gepafin.tendermanagement.model.response.SuperAdminWidgetResponseBean; import net.gepafin.tendermanagement.model.util.Response; @@ -71,4 +72,17 @@ public class DashboardApiController implements DashboardApi { return ResponseEntity.status(HttpStatus.CREATED) .body(new Response<>(widgetResponseBean, Status.SUCCESS, Translator.toLocale(GepafinConstant.DASHBOARD_WIDGET_FETCHED_SUCCESSFULLY))); } + + @Override + public ResponseEntity> getApplicationDetailsForEvaluation(HttpServletRequest request) { + + /** This code is responsible for creating user action logs for the "Get Application Details for Evaluation" operation. **/ + loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.VIEW).actionContext(UserActionContextEnum.GET_APPLICATION_DETAILS_FOR_EVALUATION).build()); + + AssignedApplicationWidgetResponseBean widgetResponseBean= dashboardService.getApplicationDetailsForEvaluation(request); + return ResponseEntity.status(HttpStatus.CREATED) + .body(new Response<>(widgetResponseBean, Status.SUCCESS, Translator.toLocale(GepafinConstant.DASHBOARD_WIDGET_FETCHED_SUCCESSFULLY))); + } + + }