Skip to content

Commit

Permalink
workflow operation and minor ui improvements (#13)
Browse files Browse the repository at this point in the history
  • Loading branch information
haiphucnguyen authored Nov 24, 2024
1 parent 2ef5eef commit 6b58679
Show file tree
Hide file tree
Showing 17 changed files with 216 additions and 55 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,6 @@ public ResponseEntity<TeamDTO> createTeam(
return ResponseEntity.status(HttpStatus.CREATED).body(createdTeam);
}

// Update an existing team
@PutMapping(consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public ResponseEntity<Team> updateTeam(
@RequestPart("teamDTO") TeamDTO team,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,16 @@

import io.flexwork.modules.collab.domain.Team;
import io.flexwork.modules.usermanagement.domain.User;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.PrePersist;
import jakarta.persistence.Table;
import java.time.LocalDateTime;
import lombok.AllArgsConstructor;
Expand Down Expand Up @@ -47,4 +51,15 @@ public class TeamRequest {
private String requestDescription;
private LocalDateTime createdDate;
private String currentState;

@Column(nullable = false, length = 50)
@Enumerated(EnumType.STRING)
private TeamRequestPriority priority;

@PrePersist
private void prePersist() {
if (createdDate == null) {
createdDate = LocalDateTime.now();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package io.flexwork.modules.teams.domain;

public enum TeamRequestPriority {
Critical,
High,
Medium,
Low,
Trivial
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package io.flexwork.modules.teams.domain;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
Expand All @@ -24,11 +26,16 @@ public class WorkflowState {
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@ManyToOne
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "workflow_id", nullable = false)
private Workflow workflow;

@Column(name = "state_name", nullable = false)
private String stateName;

@Column(name = "is_initial", nullable = false)
private Boolean isInitial;

@Column(name = "is_final", nullable = false)
private Boolean isFinal;
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,14 @@

import io.flexwork.modules.teams.domain.WorkflowState;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

@Repository
public interface WorkflowStateRepository extends JpaRepository<WorkflowState, Long> {}
public interface WorkflowStateRepository extends JpaRepository<WorkflowState, Long> {

@Query(
"SELECT ws FROM WorkflowState ws WHERE ws.workflow.id = :workflowId AND ws.isInitial = true")
WorkflowState findInitialStateByWorkflowId(@Param("workflowId") Long workflowId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@

import io.flexwork.modules.collab.service.event.NewTeamRequestCreatedEvent;
import io.flexwork.modules.teams.domain.TeamRequest;
import io.flexwork.modules.teams.domain.WorkflowState;
import io.flexwork.modules.teams.repository.TeamRequestRepository;
import io.flexwork.modules.teams.repository.WorkflowRepository;
import io.flexwork.modules.teams.repository.WorkflowStateRepository;
import io.flexwork.modules.teams.service.dto.TeamRequestDTO;
import io.flexwork.modules.teams.service.mapper.TeamRequestMapper;
import io.flexwork.query.QueryDTO;
import java.time.LocalDateTime;
import java.util.Objects;
import java.util.Optional;
import org.jclouds.rest.ResourceNotFoundException;
Expand All @@ -26,15 +28,21 @@ public class TeamRequestService {

private final TeamRequestRepository teamRequestRepository;
private final TeamRequestMapper teamRequestMapper;
private final WorkflowStateRepository workflowStateRepository;
private final WorkflowRepository workflowRepository;
private final ApplicationEventPublisher eventPublisher;

@Autowired
public TeamRequestService(
TeamRequestRepository teamRequestRepository,
TeamRequestMapper teamRequestMapper,
WorkflowRepository workflowRepository,
WorkflowStateRepository workflowStateRepository,
ApplicationEventPublisher eventPublisher) {
this.teamRequestRepository = teamRequestRepository;
this.teamRequestMapper = teamRequestMapper;
this.workflowRepository = workflowRepository;
this.workflowStateRepository = workflowStateRepository;
this.eventPublisher = eventPublisher;
}

Expand Down Expand Up @@ -65,8 +73,20 @@ public TeamRequestDTO getTeamRequestById(Long id) {

@Transactional
public TeamRequestDTO createTeamRequest(TeamRequestDTO teamRequestDTO) {

Long workflowId = teamRequestDTO.getWorkflowId();
if (workflowId == null) {
throw new ResourceNotFoundException("No workflow id found");
}
WorkflowState initialStateByWorkflowId =
workflowStateRepository.findInitialStateByWorkflowId(workflowId);
if (initialStateByWorkflowId == null) {
throw new ResourceNotFoundException(
"No initial state found for workflow id " + workflowId);
}
teamRequestDTO.setCurrentState(initialStateByWorkflowId.getStateName());

TeamRequest teamRequest = teamRequestMapper.toEntity(teamRequestDTO);
teamRequest.setCreatedDate(LocalDateTime.now());
teamRequest = teamRequestRepository.save(teamRequest);
TeamRequestDTO savedTeamRequestDTO = teamRequestMapper.toDto(teamRequest);
eventPublisher.publishEvent(new NewTeamRequestCreatedEvent(this, savedTeamRequestDTO));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,13 @@ public class TeamRequestDTO {
private String workflowName;
private Long requestUserId;
private String requestUserName;
private String requestUserImageUrl;
private Long assignUserId;
private String assignUserName;
private String assignUserImageUrl;
private String requestTitle;
private String requestDescription;
private String priority;
private LocalDateTime createdDate;
private String currentState;
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@ public interface TeamRequestMapper {
@Mapping(target = "requestUserId", source = "requestUser.id")
@Mapping(
target = "requestUserName",
expression =
"java(concatName(teamRequest.getRequestUser().getFirstName(), teamRequest.getRequestUser().getLastName()))")
source = "requestUser",
qualifiedByName = "mapUserFullName")
@Mapping(target = "requestUserImageUrl", source = "requestUser.imageUrl")
@Mapping(target = "assignUserId", source = "assignUser.id")
@Mapping(
target = "assignUserName",
expression =
"java(concatName(teamRequest.getAssignUser().getFirstName(), teamRequest.getAssignUser().getLastName()))")
@Mapping(target = "assignUserName", source = "assignUser", qualifiedByName = "mapUserFullName")
@Mapping(target = "assignUserImageUrl", source = "assignUser.imageUrl")
@Mapping(target = "teamName", source = "team.name")
@Mapping(target = "workflowId", source = "workflow.id")
@Mapping(target = "workflowName", source = "workflow.name")
TeamRequestDTO toDto(TeamRequest teamRequest);
Expand All @@ -51,10 +51,18 @@ default User toUser(Long userId) {
return (userId == null) ? null : User.builder().id(userId).build();
}

default String concatName(String firstName, String lastName) {
return firstName + " " + (lastName != null ? lastName : "");
@Named("mapUserFullName")
default String mapUserFullName(User user) {
if (user == null) {
return null;
}
String firstName = user.getFirstName() != null ? user.getFirstName() : "";
String lastName = user.getLastName() != null ? user.getLastName() : "";
return (firstName + " " + lastName).trim();
}

@BeanMapping(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE)
@Mapping(target = "assignUser", source = "assignUserId", qualifiedByName = "toUser")
@Mapping(target = "requestUser", source = "requestUserId", qualifiedByName = "toUser")
void updateEntity(TeamRequestDTO dto, @MappingTarget TeamRequest entity);
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ public ResponseEntity<TeamRequestDTO> createTeamRequest(
@PutMapping("/{id}")
public ResponseEntity<TeamRequestDTO> updateTeamRequest(
@PathVariable Long id, @RequestBody TeamRequestDTO teamRequestDTO) {
if (!id.equals(teamRequestDTO.getId())) {
throw new IllegalArgumentException("Id in URL and payload do not match");
}
return ResponseEntity.ok(teamRequestService.updateTeamRequest(id, teamRequestDTO));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ public class UserDTO implements Serializable {

private String managerName;

private String managerImageUrl;

private String about;

private String address;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ public interface UserMapper {

@Mapping(target = "managerId", source = "manager.id")
@Mapping(source = "manager", target = "managerName", qualifiedByName = "mapManagerName")
@Mapping(target = "managerImageUrl", source = "manager.imageUrl")
UserDTO toDto(User user);

User toEntity(UserDTO userDTO);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
<column name="name" type="VARCHAR(255)">
<constraints nullable="false" />
</column>
<column name="request_name" type="VARCHAR(255)">
<constraints nullable="false" />
</column>
<column name="description" type="TEXT" />
<column name="owner_id" type="BIGINT">
<constraints nullable="true" />
Expand Down Expand Up @@ -83,6 +86,9 @@
</column>
<column name="request_title" type="VARCHAR(255)" />
<column name="request_description" type="TEXT" />
<column name="priority" type="VARCHAR(50)">
<constraints nullable="false" />
</column>
<column name="created_date" type="TIMESTAMP"
defaultValueComputed="CURRENT_TIMESTAMP">
<constraints nullable="false" />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,54 @@
id;team_id;workflow_id
1;1;1
2;2;2
3;3;1
4;4;2
5;5;4
6;10;5
7;15;6
1;1;3
2;1;1
3;2;3
4;2;2
5;2;4
6;2;1
7;3;1
8;3;3
9;3;4
10;3;2
11;4;2
12;4;4
13;4;3
14;4;1
15;5;3
16;5;4
17;5;2
18;5;1
19;6;2
20;6;3
21;7;2
22;7;1
23;7;4
24;7;3
25;8;1
26;8;4
27;9;3
28;9;1
29;10;1
30;10;4
31;11;2
32;11;4
33;12;1
34;12;3
35;13;2
36;13;3
37;13;1
38;13;4
39;14;1
40;14;4
41;15;2
42;15;1
43;16;4
44;16;2
45;17;2
46;17;4
47;17;3
48;18;3
49;18;2
50;19;2
51;19;1
52;20;3
53;20;2
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
id;name;description;owner_id;visibility
1;Global Workflow 1;A global workflow available to all teams.;NULL;PUBLIC
2;Global Workflow 2;Another global workflow for all teams.;NULL;PUBLIC
3;Team Workflow 1;A private workflow for Team 1.;1;PRIVATE
4;Team Workflow 2;A workflow discoverable by other teams.;5;TEAM
5;Team Workflow 3;A private workflow for Team 10.;10;PRIVATE
6;Team Workflow 4;A global workflow with team-specific use.;NULL;PUBLIC
id;name;description;owner_id;visibility;request_name
1;Refund Process Workflow;Handles customer refund requests.;;PUBLIC;Refund
2;Bug Fix Workflow;Tracks the lifecycle of software bug fixes.;;PUBLIC;Bug
3;New Hardware Request;Manages team-specific hardware requests.;1.0;PRIVATE;Hardware Request
4;Software Approval Workflow;Tracks software license or tool requests.;1.0;PRIVATE;License Request
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
id;transition_id;action_type;action_data
1;1;NOTIFY;"{""message"":""Please provide additional evidence for your refund request.""}"
2;3;NOTIFY;"{""message"":""Refund has been approved.""}"
3;4;NOTIFY;"{""message"":""Refund request has been denied.""}"
4;5;NOTIFY;"{""message"":""Refund has been successfully completed.""}"
5;6;NOTIFY;"{""message"":""Bug has been assigned to a user.""}"
6;7;NOTIFY;"{""message"":""Bug work has started by the assignee.""}"
7;8;NOTIFY;"{""message"":""Bug has been marked as Not an Issue.""}"
8;9;NOTIFY;"{""message"":""Bug has been resolved by the assignee.""}"
9;10;NOTIFY;"{""message"":""Bug fix has been verified successfully.""}"
10;12;NOTIFY;"{""message"":""Hardware request has been submitted for manager approval.""}"
11;13;NOTIFY;"{""message"":""Hardware request approved by the manager. Awaiting IT approval.""}"
12;15;NOTIFY;"{""message"":""Hardware request approved by IT. Proceeding with procurement.""}"
13;17;NOTIFY;"{""message"":""Hardware has been successfully delivered to the requester.""}"
14;18;NOTIFY;"{""message"":""Software request submitted for manager approval.""}"
15;19;NOTIFY;"{""message"":""Software request approved by the manager. Awaiting IT approval.""}"
16;21;NOTIFY;"{""message"":""Software request approved by IT. Proceeding with procurement.""}"
17;23;NOTIFY;"{""message"":""Software has been successfully delivered to the requester.""}"
Original file line number Diff line number Diff line change
@@ -1,18 +1,25 @@
id;workflow_id;state_name;is_initial;is_final
1;1;Requested;true;false
2;1;In Progress;false;false
3;1;Completed;false;true
4;2;Open;true;false
5;2;In Review;false;false
6;2;Closed;false;true
7;3;Draft;true;false
8;3;Submitted;false;false
9;3;Approved;false;true
10;4;Initiated;true;false
11;4;Processing;false;false
12;4;Finalized;false;true
13;5;Pending Review;true;false
14;5;Reviewed;false;true
15;6;Not Started;true;false
16;6;In Execution;false;false
17;6;Completed;false;true
1;1;New;True;False
2;1;Request Evidence;False;False
3;1;Evidence Provided;False;False
4;1;Refund Approved;False;False
5;1;Refund Denied;False;True
6;1;Refund Completed;False;True
7;2;New;True;False
8;2;Assigned;False;False
9;2;In Progress;False;False
10;2;Not an Issue;False;True
11;2;Fixed;False;False
12;2;Verified;False;True
13;3;New;True;False
14;3;Manager Approval;False;False
15;3;IT Approval;False;False
16;3;Vendor Procurement;False;False
17;3;Delivered;False;True
18;3;Rejected;False;True
19;4;New;True;False
20;4;Manager Approval;False;False
21;4;IT Approval;False;False
22;4;Procurement;False;False
23;4;Delivered;False;True
24;4;Rejected;False;True
Loading

0 comments on commit 6b58679

Please sign in to comment.