From 91a274bf682249a8f1b0b317357811b33d021a33 Mon Sep 17 00:00:00 2001 From: Hai Nguyen Date: Sun, 1 Dec 2024 11:29:50 -0800 Subject: [PATCH] Update --- .../repository/TeamRequestRepository.java | 42 +++++++++++++++++ .../teams/service/TeamRequestService.java | 47 +++++++++++++++++++ .../teams/service/dto/SlaDurationDTO.java | 15 ------ .../dto/TicketActionCountByDateDTO.java | 21 +++++++++ .../teams/web/rest/TeamRequestController.java | 21 ++++++++- 5 files changed, 130 insertions(+), 16 deletions(-) delete mode 100644 server/src/main/java/io/flexwork/modules/teams/service/dto/SlaDurationDTO.java create mode 100644 server/src/main/java/io/flexwork/modules/teams/service/dto/TicketActionCountByDateDTO.java diff --git a/server/src/main/java/io/flexwork/modules/teams/repository/TeamRequestRepository.java b/server/src/main/java/io/flexwork/modules/teams/repository/TeamRequestRepository.java index 619551ad..6760f49e 100644 --- a/server/src/main/java/io/flexwork/modules/teams/repository/TeamRequestRepository.java +++ b/server/src/main/java/io/flexwork/modules/teams/repository/TeamRequestRepository.java @@ -1,9 +1,12 @@ package io.flexwork.modules.teams.repository; import io.flexwork.modules.teams.domain.TeamRequest; +import io.flexwork.modules.teams.domain.WorkflowTransitionHistoryStatus; import io.flexwork.modules.teams.service.dto.PriorityDistributionDTO; +import io.flexwork.modules.teams.service.dto.TicketActionCountByDateDTO; import io.flexwork.modules.teams.service.dto.TicketDistributionDTO; import io.flexwork.modules.usermanagement.service.dto.TicketStatisticsDTO; +import java.time.Instant; import java.util.List; import java.util.Optional; import org.springframework.data.domain.Page; @@ -124,4 +127,43 @@ List findTicketPriorityDistributionByTeamId( + "FROM TeamRequest tr " + "WHERE tr.isDeleted = false AND tr.team.id = :teamId") TicketStatisticsDTO getTicketStatisticsByTeamId(@Param("teamId") Long teamId); + + @Query( + "SELECT r " + + "FROM TeamRequest r " + + "JOIN WorkflowTransitionHistory h ON h.teamRequest.id = r.id " + + "WHERE r.isDeleted = false " + + "AND r.isCompleted = false " + + "AND h.slaDueDate IS NOT NULL " + + "AND h.slaDueDate < CURRENT_TIMESTAMP " + + "AND h.status <> :status " + + "AND r.team.id = :teamId") + List findOverdueTicketsByTeamId( + @Param("teamId") Long teamId, + @Param("status") WorkflowTransitionHistoryStatus completedStatus); + + @Query( + "SELECT COUNT(r.id) " + + "FROM TeamRequest r " + + "JOIN WorkflowTransitionHistory h ON h.teamRequest.id = r.id " + + "WHERE r.isDeleted = false " + + "AND r.isCompleted = false " + + "AND h.slaDueDate IS NOT NULL " + + "AND h.slaDueDate < CURRENT_TIMESTAMP " + + "AND h.status <> :status " + + "AND r.team.id = :teamId") + Long countOverdueTicketsByTeamId( + @Param("teamId") Long teamId, + @Param("status") WorkflowTransitionHistoryStatus completedStatus); + + @Query( + "SELECT new io.flexwork.modules.teams.service.dto.TicketActionCountByDateDTO(CAST(r.createdAt AS date), COUNT(r.id)) " + + "FROM TeamRequest r " + + "WHERE r.isDeleted = false " + + "AND r.team.id = :teamId " + + "AND r.createdAt >= :startDate " + + "GROUP BY CAST(r.createdAt AS date) " + + "ORDER BY CAST(r.createdAt AS date) ASC") + List findTicketCreationCounts( + @Param("teamId") Long teamId, @Param("startDate") Instant startDate); } diff --git a/server/src/main/java/io/flexwork/modules/teams/service/TeamRequestService.java b/server/src/main/java/io/flexwork/modules/teams/service/TeamRequestService.java index f499066f..c371c0b5 100644 --- a/server/src/main/java/io/flexwork/modules/teams/service/TeamRequestService.java +++ b/server/src/main/java/io/flexwork/modules/teams/service/TeamRequestService.java @@ -1,5 +1,6 @@ package io.flexwork.modules.teams.service; +import static io.flexwork.modules.teams.domain.WorkflowTransitionHistoryStatus.Completed; import static io.flexwork.query.QueryUtils.createSpecification; import io.flexwork.modules.audit.AuditLogUpdateEvent; @@ -14,6 +15,7 @@ import io.flexwork.modules.teams.repository.WorkflowTransitionRepository; import io.flexwork.modules.teams.service.dto.PriorityDistributionDTO; import io.flexwork.modules.teams.service.dto.TeamRequestDTO; +import io.flexwork.modules.teams.service.dto.TicketActionCountByDateDTO; import io.flexwork.modules.teams.service.dto.TicketDistributionDTO; import io.flexwork.modules.teams.service.event.NewTeamRequestCreatedEvent; import io.flexwork.modules.teams.service.event.TeamRequestWorkStateTransitionEvent; @@ -24,11 +26,16 @@ import jakarta.persistence.EntityManager; import jakarta.persistence.EntityNotFoundException; import jakarta.persistence.PersistenceContext; +import java.time.LocalDate; +import java.time.ZoneId; import java.time.ZonedDateTime; +import java.util.ArrayList; import java.util.Comparator; import java.util.List; +import java.util.Map; import java.util.Objects; import java.util.Optional; +import java.util.stream.Collectors; import org.jclouds.rest.ResourceNotFoundException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationEventPublisher; @@ -289,4 +296,44 @@ private ZonedDateTime calculateEarliestSlaDueDate(Long workflowId, Long sourceSt // Calculate the SLA due date for the earliest transition return ZonedDateTime.now().plusMinutes(earliestTransition.getSlaDuration()); } + + public List getOverdueTickets(Long teamId) { + return teamRequestRepository.findOverdueTicketsByTeamId(teamId, Completed); + } + + public Long countOverdueTickets(Long teamId) { + return teamRequestRepository.countOverdueTicketsByTeamId(teamId, Completed); + } + + public List getTicketCreationTimeseries(Long teamId, int days) { + // Default to 7 days if no input is provided + if (days <= 0) { + days = 7; + } + + // Calculate the start date based on the number of days + LocalDate startDate = LocalDate.now().minusDays(days - 1); + + // Fetch data from the repository + List results = + teamRequestRepository.findTicketCreationCounts( + teamId, startDate.atStartOfDay(ZoneId.of("UTC")).toInstant()); + + // Fill gaps for dates with no tickets + Map dateToCountMap = + results.stream() + .collect( + Collectors.toMap( + TicketActionCountByDateDTO::getDate, + TicketActionCountByDateDTO::getTicketCount)); + + List completeResults = new ArrayList<>(); + for (int i = 0; i < days; i++) { + LocalDate date = startDate.plusDays(i); + Long count = dateToCountMap.getOrDefault(date, 0L); + completeResults.add(new TicketActionCountByDateDTO(date, count)); + } + + return completeResults; + } } diff --git a/server/src/main/java/io/flexwork/modules/teams/service/dto/SlaDurationDTO.java b/server/src/main/java/io/flexwork/modules/teams/service/dto/SlaDurationDTO.java deleted file mode 100644 index a21a9357..00000000 --- a/server/src/main/java/io/flexwork/modules/teams/service/dto/SlaDurationDTO.java +++ /dev/null @@ -1,15 +0,0 @@ -package io.flexwork.modules.teams.service.dto; - -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -@Data -@NoArgsConstructor -@AllArgsConstructor -public class SlaDurationDTO { - private String sourceState; - private String targetState; - private Long slaDuration; - private String eventName; -} diff --git a/server/src/main/java/io/flexwork/modules/teams/service/dto/TicketActionCountByDateDTO.java b/server/src/main/java/io/flexwork/modules/teams/service/dto/TicketActionCountByDateDTO.java new file mode 100644 index 00000000..cadd1a59 --- /dev/null +++ b/server/src/main/java/io/flexwork/modules/teams/service/dto/TicketActionCountByDateDTO.java @@ -0,0 +1,21 @@ +package io.flexwork.modules.teams.service.dto; + +import java.sql.Date; +import java.time.LocalDate; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class TicketActionCountByDateDTO { + private LocalDate date; + private Long ticketCount; + + public TicketActionCountByDateDTO(Date creationInstant, Long ticketCount) { + // Convert Instant to LocalDate + this.date = creationInstant.toLocalDate(); + this.ticketCount = ticketCount; + } +} diff --git a/server/src/main/java/io/flexwork/modules/teams/web/rest/TeamRequestController.java b/server/src/main/java/io/flexwork/modules/teams/web/rest/TeamRequestController.java index 8ab14ff0..44ffa214 100644 --- a/server/src/main/java/io/flexwork/modules/teams/web/rest/TeamRequestController.java +++ b/server/src/main/java/io/flexwork/modules/teams/web/rest/TeamRequestController.java @@ -1,9 +1,11 @@ package io.flexwork.modules.teams.web.rest; +import io.flexwork.modules.teams.domain.TeamRequest; import io.flexwork.modules.teams.service.TeamRequestService; import io.flexwork.modules.teams.service.WorkflowTransitionHistoryService; import io.flexwork.modules.teams.service.dto.PriorityDistributionDTO; import io.flexwork.modules.teams.service.dto.TeamRequestDTO; +import io.flexwork.modules.teams.service.dto.TicketActionCountByDateDTO; import io.flexwork.modules.teams.service.dto.TicketDistributionDTO; import io.flexwork.modules.teams.service.dto.TransitionItemCollectionDTO; import io.flexwork.modules.usermanagement.service.dto.TicketStatisticsDTO; @@ -129,8 +131,25 @@ public ResponseEntity getTicketStateChangesHistory( return ResponseEntity.ok(ticketHistory); } - @GetMapping("/statistics/{teamId}") + @GetMapping("/{teamId}/statistics") public TicketStatisticsDTO getTicketStatisticsByTeamId(@PathVariable Long teamId) { return teamRequestService.getTicketStatisticsByTeamId(teamId); } + + @GetMapping("/{teamId}/overdue") + public List getOverdueTickets(@PathVariable Long teamId) { + return teamRequestService.getOverdueTickets(teamId); + } + + @GetMapping("/{teamId}/overdue/count") + public Long countOverdueTickets(@PathVariable Long teamId) { + return teamRequestService.countOverdueTickets(teamId); + } + + @GetMapping("/{teamId}/ticket-creations-day-series") + public List getTicketCreationDaySeries( + @PathVariable Long teamId, + @RequestParam(required = false, defaultValue = "7") int days) { + return teamRequestService.getTicketCreationTimeseries(teamId, days); + } }