Merge pull request #148 from Kitzanos/feature/GEPAFINBE-129

GEPAFINBE-129 (Complete Application Page)
This commit is contained in:
Rinaldo
2025-01-07 09:55:13 +01:00
committed by GitHub
13 changed files with 188 additions and 3 deletions

View File

@@ -306,7 +306,7 @@ public class ApplicationAmendmentRequestDao {
ApplicationAmendmentRequestEntity applicationAmendment = saveApplicationAmendmentRequestEntity(applicationAmendmentRequestEntity, null, VersionActionTypeEnum.INSERT);
String evaluationStatusType = applicationEvaluationEntity.getStatus();
if (Boolean.FALSE.equals(evaluationStatusType.equals((ApplicationEvaluationStatusTypeEnum.SOCCORSO.getValue())))){
applicationEvaluationEntity.setStatus(ApplicationEvaluationStatusTypeEnum.SOCCORSO.getValue());
// applicationEvaluationEntity.setStatus(ApplicationEvaluationStatusTypeEnum.SOCCORSO.getValue());
//Set Status
applicationEvaluationEntity.setStatus(ApplicationEvaluationStatusTypeEnum.SOCCORSO.getValue());

View File

@@ -24,7 +24,9 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
@@ -1800,6 +1802,11 @@ public class ApplicationEvaluationDao {
existingEntity.setClosingDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now()));
assignedApplicationsEntity.setStatus(AssignedApplicationEnum.CLOSE.getValue());
}
if (existingEntity.getStartDate() != null && existingEntity.getClosingDate() != null) {
long activeDays = ChronoUnit.DAYS.between(existingEntity.getStartDate(), existingEntity.getClosingDate());
activeDays -= existingEntity.getSuspendedDays() != null ? existingEntity.getSuspendedDays() : 0;
existingEntity.setActiveDays(activeDays);
}
entity = applicationEvaluationRepository.save(existingEntity);
assignedApplicationsRepository.save(assignedApplicationsEntity);

View File

@@ -4,6 +4,7 @@ import net.gepafin.tendermanagement.entities.*;
import net.gepafin.tendermanagement.enums.CallStatusEnum;
import net.gepafin.tendermanagement.enums.RoleStatusEnum;
import net.gepafin.tendermanagement.enums.UserStatusEnum;
import net.gepafin.tendermanagement.model.response.ApplicationWidgetResponseBean;
import net.gepafin.tendermanagement.model.response.BeneficiaryWidgetResponseBean;
import net.gepafin.tendermanagement.model.response.Widget1;
import net.gepafin.tendermanagement.model.response.SuperAdminWidgetResponseBean;
@@ -13,6 +14,10 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.math.BigDecimal;
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;
@@ -37,6 +42,9 @@ public class DashboardDao {
private BeneficiaryPreferredCallRepository beneficiaryPreferredCallRepository;
@Autowired
private ApplicationEvaluationRepository applicationEvaluationRepository;
public SuperAdminWidgetResponseBean getDashboardWidget(UserEntity requestedUserEntity) {
SuperAdminWidgetResponseBean widgetResponseBean = new SuperAdminWidgetResponseBean();
widgetResponseBean.setWidget1(createWidget1(requestedUserEntity));
@@ -133,4 +141,70 @@ public class DashboardDao {
}
return beneficiaryWidgetResponseBean;
}
public ApplicationWidgetResponseBean getApplicationDetails(UserEntity userEntity) {
ApplicationWidgetResponseBean applicationWidgetResponseBean = initializeResponseBean();
Long hubId = userEntity.getHub().getId();
setApplicationCounts(applicationWidgetResponseBean, hubId);
calculateEvaluationAverageTime(applicationWidgetResponseBean, hubId);
return applicationWidgetResponseBean;
}
private ApplicationWidgetResponseBean initializeResponseBean() {
return ApplicationWidgetResponseBean.builder()
.numberOfApplication(0L)
.numberOfAssignedApplication(0L)
.numberOfAcceptedApplication(0L)
.numberOfApplicationInAmendmentState(0L)
.numberOfDueApplication(0L)
.evaluationAverageTime(BigDecimal.ZERO)
.build();
}
private void setApplicationCounts(ApplicationWidgetResponseBean responseBean, Long hubId) {
Long activeApplications = applicationRepository.countApplicationsByHubId(hubId);
if (activeApplications != null) {
responseBean.setNumberOfApplication(activeApplications);
}
Long assignedApplications = applicationRepository.countAssignedApplicationsByHubId(hubId);
if (assignedApplications != null) {
responseBean.setNumberOfAssignedApplication(assignedApplications);
}
Long approvedApplications = applicationRepository.countApprovedApplicationsByHubId(hubId);
if (approvedApplications != null) {
responseBean.setNumberOfAcceptedApplication(approvedApplications);
}
Long soccorsoApplications = applicationRepository.countSoccorsoApplicationsByHubId(hubId);
if (soccorsoApplications != null) {
responseBean.setNumberOfApplicationInAmendmentState(soccorsoApplications);
}
}
private void calculateEvaluationAverageTime(ApplicationWidgetResponseBean responseBean, Long hubId) {
List<Long> applicationIds = applicationRepository.findApplicationIdsByHubId(hubId);
if (Boolean.FALSE.equals(applicationIds.isEmpty())) {
BigDecimal averageTime = applicationEvaluationRepository.findAverageEvaluationTimeByApplicationIds(applicationIds);
responseBean.setEvaluationAverageTime(averageTime != null ? averageTime : BigDecimal.ZERO);
}
LocalDate twoDaysLater = LocalDate.now().plusDays(2);
Long dueApplications = applicationEvaluationRepository.countDueApplicationsBetween(
applicationIds,
LocalDate.now(),
twoDaysLater
);
if (dueApplications != null) {
responseBean.setNumberOfDueApplication(dueApplications);
}
}
}

View File

@@ -65,4 +65,7 @@ public class ApplicationEvaluationEntity extends BaseEntity{
@Column(name = "CLOSING_DATE")
private LocalDateTime closingDate;
@Column(name = "ACTIVE_DAYS")
private Long activeDays;
}

View File

@@ -136,6 +136,7 @@ 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_APPLICATION_DETAILS("GET_APPLICATION_DETAILS"),
/** Evaluation criteria action context **/
GET_EVALUATION_CRITERIA("GET_EVALUATION_CRITERIA"),

View File

@@ -0,0 +1,23 @@
package net.gepafin.tendermanagement.model.response;
import lombok.Builder;
import lombok.Data;
import java.math.BigDecimal;
@Builder
@Data
public class ApplicationWidgetResponseBean {
private Long numberOfApplication;
private Long numberOfAssignedApplication;
private Long numberOfAcceptedApplication;
private Long numberOfApplicationInAmendmentState;
private Long numberOfDueApplication;
private BigDecimal evaluationAverageTime;
}

View File

@@ -7,6 +7,8 @@ import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;
@@ -31,4 +33,27 @@ public interface ApplicationEvaluationRepository extends JpaRepository<Applicati
@Query("SELECT a FROM ApplicationEvaluationEntity a WHERE a.isDeleted = false AND a.endDate < :currentDate")
List<ApplicationEvaluationEntity> findAllByIsDeletedFalseAndEndDateBefore(@Param("currentDate") LocalDateTime currentDate);
// @Query("SELECT AVG(DATEDIFF(DAY, e.startDate, e.endDate)) FROM ApplicationEvaluationEntity e WHERE e.applicationId IN :applicationIds AND e.startDate IS NOT NULL AND e.endDate IS NOT NULL AND e.isDeleted = false ")
@Query("""
SELECT AVG(e.activeDays)
FROM ApplicationEvaluationEntity e
WHERE e.applicationId IN :applicationIds
AND e.activeDays IS NOT NULL
AND e.isDeleted = false
""")
BigDecimal findAverageEvaluationTimeByApplicationIds(@Param("applicationIds") List<Long> applicationIds);
@Query("""
SELECT COUNT(e)
FROM ApplicationEvaluationEntity e
WHERE e.applicationId IN :applicationIds
AND FUNCTION('DATE', e.endDate) BETWEEN :startDate AND :endDate
AND e.isDeleted = false
""")
Long countDueApplicationsBetween(
@Param("applicationIds") List<Long> applicationIds,
@Param("startDate") LocalDate startDate,
@Param("endDate") LocalDate endDate
);
}

View File

@@ -44,4 +44,20 @@ public interface ApplicationRepository extends JpaRepository<ApplicationEntity,
@Query("SELECT a.call.id FROM ApplicationEntity a WHERE a.id = :id AND a.isDeleted = false")
Long findCallIdById(@Param("id") Long id);
@Query("SELECT COUNT(a) FROM ApplicationEntity a WHERE a.hubId = :hubId AND a.status = 'SUBMIT' AND a.isDeleted = false")
public Long countApplicationsByHubId(@Param("hubId") Long hubId);
@Query("SELECT COUNT(a) FROM ApplicationEntity a WHERE a.hubId = :hubId AND a.status = 'EVALUATION' AND a.isDeleted = false")
Long countAssignedApplicationsByHubId(@Param("hubId") Long hubId);
@Query("SELECT COUNT(a) FROM ApplicationEntity a WHERE a.hubId = :hubId AND a.status = 'APPROVED' AND a.isDeleted = false")
Long countApprovedApplicationsByHubId(@Param("hubId") Long hubId);
@Query("SELECT COUNT(a) FROM ApplicationEntity a WHERE a.hubId = :hubId AND a.status = 'SOCCORSO' AND a.isDeleted = false")
Long countSoccorsoApplicationsByHubId(@Param("hubId") Long hubId);
@Query("SELECT a.id FROM ApplicationEntity a WHERE a.hubId = :hubId AND a.isDeleted = false")
List<Long> findApplicationIdsByHubId(@Param("hubId") Long hubId);
}

View File

@@ -1,6 +1,7 @@
package net.gepafin.tendermanagement.service;
import jakarta.servlet.http.HttpServletRequest;
import net.gepafin.tendermanagement.model.response.ApplicationWidgetResponseBean;
import net.gepafin.tendermanagement.model.response.BeneficiaryWidgetResponseBean;
import net.gepafin.tendermanagement.model.response.SuperAdminWidgetResponseBean;
@@ -9,5 +10,5 @@ public interface DashboardService {
public SuperAdminWidgetResponseBean getDashboardWidgetForSuperAdmin(HttpServletRequest request);
public BeneficiaryWidgetResponseBean getDashboardWidgetForBeneficiary(HttpServletRequest request, Long companyId);
public ApplicationWidgetResponseBean getApplicationDetails(HttpServletRequest request);
}

View File

@@ -4,6 +4,7 @@ import jakarta.servlet.http.HttpServletRequest;
import net.gepafin.tendermanagement.dao.DashboardDao;
import net.gepafin.tendermanagement.entities.CompanyEntity;
import net.gepafin.tendermanagement.entities.UserEntity;
import net.gepafin.tendermanagement.model.response.ApplicationWidgetResponseBean;
import net.gepafin.tendermanagement.model.response.BeneficiaryWidgetResponseBean;
import net.gepafin.tendermanagement.model.response.SuperAdminWidgetResponseBean;
import net.gepafin.tendermanagement.service.DashboardService;
@@ -32,4 +33,10 @@ public class DashboardServiceImpl implements DashboardService {
CompanyEntity company = validator.validateUserWithCompany(request, companyId);
return dashboardDao.getDashboardWidgetForBeneficiary(userEntity, company);
}
@Override
public ApplicationWidgetResponseBean getApplicationDetails(HttpServletRequest request) {
UserEntity userEntity=validator.validateUser(request);
return dashboardDao.getApplicationDetails(userEntity);
}
}

View File

@@ -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.model.response.ApplicationWidgetResponseBean;
import net.gepafin.tendermanagement.model.response.BeneficiaryWidgetResponseBean;
import net.gepafin.tendermanagement.model.response.SuperAdminWidgetResponseBean;
import net.gepafin.tendermanagement.model.util.Response;
@@ -46,7 +47,19 @@ public interface DashboardApi {
produces = { "application/json" })
ResponseEntity<Response<BeneficiaryWidgetResponseBean>> getDashboardWidgetForBeneficiary(HttpServletRequest request,
@Parameter(description = "The company id", required = true) @PathVariable(value = "companyId", required = true) Long companyId);
@Operation(summary = "Api to get Application details",
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 = "/application",
produces = { "application/json" })
@PreAuthorize("hasRole('ROLE_SUPER_ADMIN') || hasRole('ROLE_INSTRUCTOR_MANAGER')")
ResponseEntity<Response<ApplicationWidgetResponseBean>> getApplicationDetails(HttpServletRequest request);
}

View File

@@ -6,6 +6,7 @@ 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.ApplicationWidgetResponseBean;
import net.gepafin.tendermanagement.model.response.BeneficiaryWidgetResponseBean;
import net.gepafin.tendermanagement.model.response.SuperAdminWidgetResponseBean;
import net.gepafin.tendermanagement.model.util.Response;
@@ -49,5 +50,14 @@ 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<Response<ApplicationWidgetResponseBean>> getApplicationDetails(HttpServletRequest request) {
/** This code is responsible for creating user action logs for the "Get complete application page" operation. **/
loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.VIEW).actionContext(UserActionContextEnum.GET_APPLICATION_DETAILS).build());
ApplicationWidgetResponseBean widgetResponseBean= dashboardService.getApplicationDetails(request);
return ResponseEntity.status(HttpStatus.CREATED)
.body(new Response<>(widgetResponseBean, Status.SUCCESS, Translator.toLocale(GepafinConstant.DASHBOARD_WIDGET_FETCHED_SUCCESSFULLY)));
}
}