first commit

This commit is contained in:
Your NamebaishaliHolocron
2026-06-15 12:57:03 +05:30
commit b9ac5ae0b2
398 changed files with 49583 additions and 0 deletions

39
backend/.gitignore vendored Normal file
View File

@@ -0,0 +1,39 @@
HELP.md
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/
../.vscode/
../logs/
logs/

51
backend/Dockerfile Normal file
View File

@@ -0,0 +1,51 @@
# Stage 1: Build
FROM maven:3.9-eclipse-temurin-21 AS builder
WORKDIR /build
# Copy the parent pom and all module poms first for better layer caching
COPY backend/pom.xml ./pom.xml
COPY backend/projectmanagement-client/pom.xml projectmanagement-client/
COPY backend/projectmanagement-server/pom.xml projectmanagement-server/
RUN mvn dependency:go-offline -B
# Copy the entire backend source code
COPY backend/ .
# 4. Build the application
RUN mvn -pl projectmanagement-server -am clean package \
-DskipTests -Dmaven.javadoc.skip=true
# =======================
# Runtime Image
# =======================
FROM eclipse-temurin:21-jre-alpine
WORKDIR /app
# Create user and group
RUN addgroup -S spring && adduser -S spring -G spring
# Copy the built JAR from builder stage
COPY --from=builder /build/projectmanagement-server/target/*.jar app.jar
# Create directories and set permissions
RUN mkdir -p /app/logs /app/bpmn && \
chown -R spring:spring /app/logs /app
# Copy BPMN files
# NOTE: This expects a 'bpmn' folder in your project root
COPY --chown=spring:spring bpmn/ /app/bpmn/
USER spring
EXPOSE 8071
# Environment setup
ENV IKON_ACCESSMANAGEMENT_INIT_FILE=/app/bpmn/project.json
ENV IKON_PROCESSENGINE_BPMN_PATH=/app/bpmn
ENV JAVA_OPTS="-XX:+UseContainerSupport -XX:MaxRAMPercentage=75.0"
# Run the application
ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar app.jar"]

17
backend/README.md Normal file
View File

@@ -0,0 +1,17 @@
# Getting Started
### Reference Documentation
For further reference, please consider the following sections:
* [Official Apache Maven documentation](https://maven.apache.org/guides/index.html)
* [Spring Boot Maven Plugin Reference Guide](https://docs.spring.io/spring-boot/3.4.4/maven-plugin)
* [Create an OCI image](https://docs.spring.io/spring-boot/3.4.4/maven-plugin/build-image.html)
* [Spring Boot DevTools](https://docs.spring.io/spring-boot/3.4.4/reference/using/devtools.html)
### Maven Parent overrides
Due to Maven's design, elements are inherited from the parent POM to the project POM.
While most of the inheritance is fine, it also inherits unwanted elements like `<license>` and `<developers>` from the parent.
To prevent this, the project POM contains empty overrides for these elements.
If you manually switch to a different parent and actually want the inheritance, you need to remove those overrides.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

95
backend/pom.xml Normal file
View File

@@ -0,0 +1,95 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.4.4</version>
<relativePath/>
</parent>
<groupId>com.ikon.projectmanagement</groupId> <!-- lookup parent from repository -->
<artifactId>projectmanagement</artifactId><!-- lookup parent from repository -->
<version>1.0.0</version>
<packaging>pom</packaging>
<name>projectmanagement</name><!-- lookup parent from repository -->
<url/>
<licenses>
<license/>
</licenses>
<developers>
<developer/>
</developers>
<scm>
<connection/>
<developerConnection/>
<tag/>
<url/>
</scm>
<properties>
<maven.compiler.release>21</maven.compiler.release>
<java.version>21</java.version>
<spring-cloud.version>2024.0.0</spring-cloud.version>
<graalvm.version>24.1.1</graalvm.version>
<avro.version>1.12.0</avro.version>
<avro-serializer.version>7.8.0</avro-serializer.version>
<ikon.sdk.version>1.0.0</ikon.sdk.version>
<projectmanagement.version>1.0.0</projectmanagement.version>
</properties>
<repositories>
<repository>
<id>maven-central</id>
<name>Maven Central Repository</name>
<url>https://ikon-vpm.keross.com/nexus/repository/maven-central</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>ikon-nexus</id>
<name>Ikon Repository</name>
<url>https://ikon-vpm.keross.com/nexus/repository/maven-releases</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<distributionManagement>
<!--<repository>
<id>ikon-repository</id>
<name>Ikon Repository</name>
<url>https://ikon-vpm.keross.com/nexus/repository/maven-releases</url>
</repository>-->
<repository>
<id>ikon-apps-lib-dist</id>
<name>Ikon App Lib Repository</name>
<url>https://ikon-vpm.keross.com/nexus/repository/ikon-apps-lib-dist/</url>
</repository>
</distributionManagement>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<modules>
<module>projectmanagement-client</module>
<module>projectmanagement-server</module>
</modules>
</project>

View File

@@ -0,0 +1,73 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.ikon.projectmanagement</groupId>
<artifactId>projectmanagement</artifactId>
<version>1.0.0</version>
</parent>
<artifactId>projectmanagement-client</artifactId>
<dependencies>
<dependency>
<groupId>com.ikon</groupId>
<artifactId>ikon-core</artifactId>
<version>${ikon.sdk.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>1.8.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
<build>
<plugins>
<!-- Attach source JAR -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- Attach Javadoc JAR -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,36 @@
package com.ikon.projectmanagement.api;
import java.util.List;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import com.ikon.projectmanagement.dto.response.DashboardWidgetsResponseDto;
import com.ikon.projectmanagement.dto.response.StatusWiseProjectResponseData;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
@Tag(name = "Dashboard", description = "APIs for managing dashboard")
@RequestMapping("/api/v1/dashboard")
public interface DashboardApi {
@Operation(summary = "Get dashboard widgets data", description = "Retrieves the data for the dashboard widgets.", responses = {
@ApiResponse(responseCode = "200", description = "Widgets data retrieved successfully"),
@ApiResponse(responseCode = "401", description = "Unauthorized"),
@ApiResponse(responseCode = "500", description = "Internal server error")
})
@GetMapping("/widgets")
ResponseEntity<DashboardWidgetsResponseDto> getWidgetsData(
@RequestHeader("Authorization") String accessToken);
@Operation(summary = "Get status-wise project data", description = "Retrieves the project data based on their status.", responses = {
@ApiResponse(responseCode = "200", description = "Project data retrieved successfully"),
@ApiResponse(responseCode = "401", description = "Unauthorized"),
@ApiResponse(responseCode = "500", description = "Internal server error")
})
@GetMapping("/status-wise-projects")
ResponseEntity<List<StatusWiseProjectResponseData>> getStatusWiseProjectData(
@RequestHeader("Authorization") String accessToken);
}

View File

@@ -0,0 +1,44 @@
package com.ikon.projectmanagement.api;
import com.ikon.projectmanagement.dto.request.EmployeeRequestDto;
import com.ikon.projectmanagement.dto.response.EmployeeResponseDto;
import java.util.List;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseStatus;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
@Tag(name = "Employee APIs", description = "APIs for managing local employees")
@RequestMapping("/api/v1/employees")
public interface EmployeeApi {
@Operation(summary = "Get all employees")
@GetMapping
ResponseEntity<List<EmployeeResponseDto>> getAllEmployees();
@Operation(summary = "Get employee by ID")
@GetMapping("/{id}")
ResponseEntity<EmployeeResponseDto> getEmployeeById(@PathVariable String id);
@Operation(summary = "Create a new employee")
@PostMapping
@ResponseStatus(HttpStatus.CREATED)
ResponseEntity<EmployeeResponseDto> createEmployee(@RequestBody EmployeeRequestDto dto);
@Operation(summary = "Update an existing employee")
@PutMapping("/{id}")
ResponseEntity<EmployeeResponseDto> updateEmployee(@PathVariable String id, @RequestBody EmployeeRequestDto dto);
@Operation(summary = "Delete an employee")
@DeleteMapping("/{id}")
@ResponseStatus(HttpStatus.NO_CONTENT)
ResponseEntity<Void> deleteEmployee(@PathVariable String id);
}

View File

@@ -0,0 +1,40 @@
package com.ikon.projectmanagement.api;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestHeader;
import com.ikon.projectmanagement.dto.response.FxRateResponseDto;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.web.bind.annotation.*;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
@Tag(name = "FX Rate APIs", description = "FX Rate configuration APIs")
@RequestMapping("/api/v1/fx-rate")
public interface FxRateApi {
@Operation(summary = "Get all FX rate configurations", description = "Fetches all FX rate configurations.", responses = {
@ApiResponse(responseCode = "200", description = "FX rate list fetched successfully"),
@ApiResponse(responseCode = "500", description = "Internal server error")
})
@GetMapping
ResponseEntity<Page<FxRateResponseDto>> getAllFxRates(
@RequestHeader("Authorization") String accessToken,
Pageable pageable);
@Operation(summary = "Get FX rate by year", description = "Fetches FX rate configuration by year.", parameters = {
@Parameter(name = "year", description = "Identifier of the year")
}, responses = {
@ApiResponse(responseCode = "200", description = "FX rate fetched successfully"),
@ApiResponse(responseCode = "404", description = "FX rate not found"),
@ApiResponse(responseCode = "500", description = "Internal server error")
})
@GetMapping("/year={year}")
ResponseEntity<FxRateResponseDto> getFxRateByYear(
@RequestHeader("Authorization") String accessToken,
@PathVariable String year);
}

View File

@@ -0,0 +1,45 @@
package com.ikon.projectmanagement.api;
import com.ikon.projectmanagement.dto.request.GradeRequestDto;
import com.ikon.projectmanagement.dto.response.GradeResponseDto;
import java.util.List;
import java.util.UUID;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseStatus;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
@Tag(name = "Grade APIs", description = "APIs for managing local grades")
@RequestMapping("/api/v1/grades")
public interface GradeApi {
@Operation(summary = "Get all grades")
@GetMapping
ResponseEntity<List<GradeResponseDto>> getAllGrades();
@Operation(summary = "Get grade by ID")
@GetMapping("/{id}")
ResponseEntity<GradeResponseDto> getGradeById(@PathVariable UUID id);
@Operation(summary = "Create a new grade")
@PostMapping
@ResponseStatus(HttpStatus.CREATED)
ResponseEntity<GradeResponseDto> createGrade(@RequestBody GradeRequestDto dto);
@Operation(summary = "Update an existing grade")
@PutMapping("/{id}")
ResponseEntity<GradeResponseDto> updateGrade(@PathVariable UUID id, @RequestBody GradeRequestDto dto);
@Operation(summary = "Delete a grade")
@DeleteMapping("/{id}")
@ResponseStatus(HttpStatus.NO_CONTENT)
ResponseEntity<Void> deleteGrade(@PathVariable UUID id);
}

View File

@@ -0,0 +1,22 @@
package com.ikon.projectmanagement.api;
import java.util.List;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import com.ikon.projectmanagement.dto.response.EmployeeResponseDto;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
@Tag(name = "Import Employee API", description = "API for importing Employee master data from Sales CRM")
@RequestMapping("/import-data/employees")
public interface ImportEmployeeApi {
@Operation(summary = "Fetch all employees from Sales CRM and persist locally")
@GetMapping
ResponseEntity<List<EmployeeResponseDto>> fetchAllEmployees(@RequestHeader("Authorization") String accessToken);
}

View File

@@ -0,0 +1,22 @@
package com.ikon.projectmanagement.api;
import java.util.List;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import com.ikon.projectmanagement.dto.response.FxRateDto;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
@Tag(name = "Import FX Rate API", description = "API for importing FX Rate master data from Sales CRM")
@RequestMapping("/import-data/fx-rates")
public interface ImportFxRateApi {
@Operation(summary = "Fetch all FX rates from Sales CRM and persist locally")
@GetMapping
ResponseEntity<List<FxRateDto>> fetchAllFxRates(@RequestHeader("Authorization") String accessToken);
}

View File

@@ -0,0 +1,22 @@
package com.ikon.projectmanagement.api;
import java.util.List;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import com.ikon.projectmanagement.dto.response.GradeResponseDto;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
@Tag(name = "Import Grade API", description = "API for importing Grade master data from Sales CRM")
@RequestMapping("/import-data/grades")
public interface ImportGradeApi {
@Operation(summary = "Fetch all grades from Sales CRM and persist locally")
@GetMapping
ResponseEntity<List<GradeResponseDto>> fetchAllGrades(@RequestHeader("Authorization") String accessToken);
}

View File

@@ -0,0 +1,22 @@
package com.ikon.projectmanagement.api;
import java.util.List;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import com.ikon.projectmanagement.dto.response.RoleResponseDto;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
@Tag(name = "Import Role API", description = "API for importing Role master data from Sales CRM")
@RequestMapping("/import-data/roles")
public interface ImportRoleApi {
@Operation(summary = "Fetch all roles from Sales CRM and persist locally")
@GetMapping
ResponseEntity<List<RoleResponseDto>> fetchAllRoles(@RequestHeader("Authorization") String accessToken);
}

View File

@@ -0,0 +1,22 @@
package com.ikon.projectmanagement.api;
import java.util.List;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import com.ikon.projectmanagement.dto.response.WorkingDayDto;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
@Tag(name = "Import Working Day API", description = "API for importing Working Day master data from Sales CRM")
@RequestMapping("/import-data/working-days")
public interface ImportWorkingDayApi {
@Operation(summary = "Fetch all working days from Sales CRM and persist locally")
@GetMapping
ResponseEntity<List<WorkingDayDto>> fetchAllWorkingDays(@RequestHeader("Authorization") String accessToken);
}

View File

@@ -0,0 +1,76 @@
package com.ikon.projectmanagement.api;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
import java.util.List;
import java.util.UUID;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import com.ikon.projectmanagement.dto.request.IssueCreateRequestDto;
import com.ikon.projectmanagement.dto.response.IssueResponseDto;
@Tag(name = "Issue APIs", description = "Issue Management related APIs")
@RequestMapping("/api/v1/issues")
public interface IssueApi {
// ================= CREATE =================
@Operation(summary = "Create a new issue", description = "Creates a new issue and returns the created issue details.", requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(description = "Issue details", required = true, content = @Content(schema = @Schema(implementation = IssueCreateRequestDto.class))), responses = {
@ApiResponse(responseCode = "201", description = "Issue created successfully"),
@ApiResponse(responseCode = "400", description = "Invalid issue data"),
@ApiResponse(responseCode = "401", description = "Unauthorized"),
@ApiResponse(responseCode = "500", description = "Internal server error")
})
@PostMapping
ResponseEntity<IssueResponseDto> createIssue(
@RequestHeader("Authorization") String accessToken,
@RequestBody IssueCreateRequestDto issueCreateRequestDto);
// ================= READ ALL =================
@Operation(summary = "Get all issues", description = "Retrieves a list of all existing issues.", responses = {
@ApiResponse(responseCode = "200", description = "Issues retrieved successfully"),
@ApiResponse(responseCode = "401", description = "Unauthorized"),
@ApiResponse(responseCode = "500", description = "Internal server error")
})
@GetMapping("/project/{projectIdentifier}")
ResponseEntity<List<IssueResponseDto>> getAllIssues(
@RequestHeader("Authorization") String accessToken,
@PathVariable("projectIdentifier") UUID projectIdentifier);
// ================= READ BY ID =================
@Operation(summary = "Get issue by ID", description = "Retrieves an issue by its unique issue ID.", responses = {
@ApiResponse(responseCode = "200", description = "Issue retrieved successfully"),
@ApiResponse(responseCode = "401", description = "Unauthorized"),
@ApiResponse(responseCode = "404", description = "Issue not found"),
@ApiResponse(responseCode = "500", description = "Internal server error")
})
@GetMapping("/{issueId}")
ResponseEntity<IssueResponseDto> getIssueById(
@RequestHeader("Authorization") String accessToken,
@PathVariable("issueId") UUID issueId);
// ================= UPDATE =================
@Operation(summary = "Update an existing issue", description = "Updates the details of an existing issue identified by its ID.", requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(description = "Updated issue details", required = true, content = @Content(schema = @Schema(implementation = IssueCreateRequestDto.class))), responses = {
@ApiResponse(responseCode = "200", description = "Issue updated successfully"),
@ApiResponse(responseCode = "400", description = "Invalid issue data or ID provided"),
@ApiResponse(responseCode = "401", description = "Unauthorized"),
@ApiResponse(responseCode = "404", description = "Issue not found"),
@ApiResponse(responseCode = "500", description = "Internal server error")
})
@PutMapping("/{issueId}")
ResponseEntity<IssueResponseDto> updateIssue(
@RequestHeader("Authorization") String accessToken,
@PathVariable("issueId") UUID issueId,
@RequestBody IssueCreateRequestDto issueCreateRequestDto);
}

View File

@@ -0,0 +1,91 @@
package com.ikon.projectmanagement.api;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
import java.util.List;
import java.util.UUID;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import com.ikon.projectmanagement.dto.request.MeetingRequestDTO;
import com.ikon.projectmanagement.dto.response.MeetingResponseDTO;
@Tag(name = "Meeting APIs", description = "Meeting Management related APIs")
@RequestMapping("/api/v1/meetings")
public interface MeetingApi {
// ================= CREATE =================
@Operation(summary = "Create a new meeting", description = "Creates a new meeting and returns the created meeting details.", requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(description = "Meeting details", required = true, content = @Content(schema = @Schema(implementation = MeetingRequestDTO.class))), responses = {
@ApiResponse(responseCode = "201", description = "Meeting created successfully"),
@ApiResponse(responseCode = "400", description = "Invalid meeting data"),
@ApiResponse(responseCode = "401", description = "Unauthorized"),
@ApiResponse(responseCode = "500", description = "Internal server error")
})
@PostMapping
ResponseEntity<MeetingResponseDTO> createMeeting(
@RequestHeader("Authorization") String accessToken,
@RequestBody MeetingRequestDTO meetingRequestDTO);
// ================= READ ALL BY PROJECT ID =================
@Operation(summary = "Get all meetings by project ID", description = "Retrieves a list of all meetings for a given project using project UUID.", responses = {
@ApiResponse(responseCode = "200", description = "Meetings retrieved successfully"),
@ApiResponse(responseCode = "401", description = "Unauthorized"),
@ApiResponse(responseCode = "500", description = "Internal server error")
})
@GetMapping("/project/{projectIdentifier}")
ResponseEntity<List<MeetingResponseDTO>> getAllMeetings(
@RequestHeader("Authorization") String accessToken,
@PathVariable("projectIdentifier") UUID projectIdentifier);
// ================= READ ALL BY PROJECT IDENTIFIER =================
// ================= READ BY ID =================
@Operation(summary = "Get meeting by ID", description = "Retrieves a meeting by its unique meeting ID.", responses = {
@ApiResponse(responseCode = "200", description = "Meeting retrieved successfully"),
@ApiResponse(responseCode = "401", description = "Unauthorized"),
@ApiResponse(responseCode = "404", description = "Meeting not found"),
@ApiResponse(responseCode = "500", description = "Internal server error")
})
@GetMapping("/{meetingId}")
ResponseEntity<MeetingResponseDTO> getMeetingById(
@RequestHeader("Authorization") String accessToken,
@PathVariable("meetingId") UUID meetingId);
// ================= UPDATE =================
@Operation(summary = "Update an existing meeting", description = "Updates the details of an existing meeting identified by its ID.", requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(description = "Updated meeting details", required = true, content = @Content(schema = @Schema(implementation = MeetingRequestDTO.class))), responses = {
@ApiResponse(responseCode = "200", description = "Meeting updated successfully"),
@ApiResponse(responseCode = "400", description = "Invalid meeting data or ID provided"),
@ApiResponse(responseCode = "401", description = "Unauthorized"),
@ApiResponse(responseCode = "404", description = "Meeting not found"),
@ApiResponse(responseCode = "500", description = "Internal server error")
})
@PutMapping("/{meetingId}")
ResponseEntity<MeetingResponseDTO> updateMeeting(
@RequestHeader("Authorization") String accessToken,
@PathVariable("meetingId") UUID meetingId,
@RequestBody MeetingRequestDTO meetingRequestDTO);
// ================= DELETE =================
@Operation(summary = "Delete a meeting", description = "Deletes a meeting identified by its unique meeting ID.", responses = {
@ApiResponse(responseCode = "204", description = "Meeting deleted successfully"),
@ApiResponse(responseCode = "401", description = "Unauthorized"),
@ApiResponse(responseCode = "404", description = "Meeting not found"),
@ApiResponse(responseCode = "500", description = "Internal server error")
})
@DeleteMapping("/{meetingId}")
ResponseEntity<Void> deleteMeeting(
@RequestHeader("Authorization") String accessToken,
@PathVariable("meetingId") UUID meetingId);
}

View File

@@ -0,0 +1,74 @@
package com.ikon.projectmanagement.api;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
import java.util.List;
import java.util.UUID;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import com.ikon.projectmanagement.dto.request.ProductOfProjectRequestDto;
import com.ikon.projectmanagement.dto.request.WorkflowTransitionRequestDto;
import com.ikon.projectmanagement.dto.response.ProductOfProjectResponseDto;
@Tag(name = "Product APIs", description = "Product Of Project Management related APIs")
@RequestMapping("/api/v1/projects")
public interface ProductOfProjectApi {
@Operation(summary = "Get all products", description = "Retrieves a list of all existing products.", responses = {
@ApiResponse(responseCode = "200", description = "Products retrieved successfully"),
@ApiResponse(responseCode = "401", description = "Unauthorized"),
@ApiResponse(responseCode = "500", description = "Internal server error")
})
@GetMapping("/{projectIdentifier}/products")
ResponseEntity<List<ProductOfProjectResponseDto>> getAllProductsByProject(
@RequestHeader("Authorization") String accessToken,
@PathVariable("projectIdentifier") UUID projectIdentifier);
@Operation(summary = "Get product by product identifier", description = "Retrieves a single product under a project (account + project scoped).", responses = {
@ApiResponse(responseCode = "200", description = "Product retrieved successfully"),
@ApiResponse(responseCode = "401", description = "Unauthorized"),
@ApiResponse(responseCode = "404", description = "Product not found"),
@ApiResponse(responseCode = "500", description = "Internal server error")
})
@GetMapping("/{projectIdentifier}/products/{productIdentifier}")
ResponseEntity<ProductOfProjectResponseDto> getProductById(
@RequestHeader("Authorization") String accessToken,
@PathVariable("projectIdentifier") UUID projectIdentifier,
@PathVariable("productIdentifier") UUID productIdentifier);
// ================= UPDATE PRODUCT =================
@Operation(summary = "Update an existing product", description = "Updates a product under a specific project (secure multi-tenant update).", requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(description = "Updated product details", required = true, content = @Content(schema = @Schema(implementation = ProductOfProjectRequestDto.class))), responses = {
@ApiResponse(responseCode = "200", description = "Product updated successfully"),
@ApiResponse(responseCode = "400", description = "Invalid product data"),
@ApiResponse(responseCode = "401", description = "Unauthorized"),
@ApiResponse(responseCode = "404", description = "Product not found"),
@ApiResponse(responseCode = "500", description = "Internal server error")
})
@PutMapping("/{projectIdentifier}/products/{productIdentifier}")
ResponseEntity<ProductOfProjectResponseDto> updateProduct(
@RequestHeader("Authorization") String accessToken,
@PathVariable("projectIdentifier") UUID projectIdentifier,
@PathVariable("productIdentifier") UUID productIdentifier,
@RequestBody ProductOfProjectRequestDto productDto);
// ================= WORKFLOW STAGE TRANSITION =================
@Operation(summary = "Transition product workflow stage", description = "Transitions the product to a new workflow stage with validation. The Schedule → Resources & Expenses transition requires schedule data to exist.", requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(description = "Transition request with target status", required = true, content = @Content(schema = @Schema(implementation = WorkflowTransitionRequestDto.class))), responses = {
@ApiResponse(responseCode = "200", description = "Transition successful"),
@ApiResponse(responseCode = "400", description = "Transition not allowed or preconditions not met"),
@ApiResponse(responseCode = "401", description = "Unauthorized"),
@ApiResponse(responseCode = "404", description = "Product not found"),
@ApiResponse(responseCode = "500", description = "Internal server error")
})
@PostMapping("/{projectIdentifier}/products/{productIdentifier}/transition")
ResponseEntity<ProductOfProjectResponseDto> transitionProductStatus(
@RequestHeader("Authorization") String accessToken,
@PathVariable("projectIdentifier") UUID projectIdentifier,
@PathVariable("productIdentifier") UUID productIdentifier,
@RequestBody WorkflowTransitionRequestDto transitionDto);
}

View File

@@ -0,0 +1,81 @@
package com.ikon.projectmanagement.api;
import com.ikon.projectmanagement.dto.request.ProductPSResourceAllocationRequestDto;
import com.ikon.projectmanagement.dto.response.ProductPSResourceAllocationResponseDto;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.UUID;
@Tag(name = "Product Resource Allocation APIs", description = "Product resource allocation management APIs")
@RequestMapping("/api/v1/products")
public interface ProductResourceAllocationApi {
@Operation(summary = "Get product resource allocations", description = "Retrieves all resource allocations for a product.", responses = {
@ApiResponse(responseCode = "200", description = "Allocations retrieved successfully"),
@ApiResponse(responseCode = "401", description = "Unauthorized"),
@ApiResponse(responseCode = "404", description = "Product not found"),
@ApiResponse(responseCode = "500", description = "Internal server error")
})
@GetMapping("/{productIdentifier}/resource-allocations")
ResponseEntity<List<ProductPSResourceAllocationResponseDto>> getResourceAllocations(
@RequestHeader("Authorization") String accessToken,
@PathVariable("productIdentifier") UUID productIdentifier);
@Operation(summary = "Get resource allocation", description = "Retrieves a single resource allocation by its ID.", responses = {
@ApiResponse(responseCode = "200", description = "Allocation retrieved successfully"),
@ApiResponse(responseCode = "401", description = "Unauthorized"),
@ApiResponse(responseCode = "404", description = "Allocation not found"),
@ApiResponse(responseCode = "500", description = "Internal server error")
})
@GetMapping("/{productIdentifier}/resource-allocations/{allocationIdentifier}")
ResponseEntity<ProductPSResourceAllocationResponseDto> getResourceAllocation(
@RequestHeader("Authorization") String accessToken,
@PathVariable("productIdentifier") UUID productIdentifier,
@PathVariable("allocationIdentifier") UUID allocationIdentifier);
@Operation(summary = "Create resource allocation", description = "Creates a new resource allocation for a product.", requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(description = "New allocation details", required = true, content = @Content(schema = @Schema(implementation = ProductPSResourceAllocationRequestDto.class))), responses = {
@ApiResponse(responseCode = "201", description = "Allocation created successfully"),
@ApiResponse(responseCode = "400", description = "Invalid allocation data"),
@ApiResponse(responseCode = "401", description = "Unauthorized"),
@ApiResponse(responseCode = "404", description = "Product not found"),
@ApiResponse(responseCode = "500", description = "Internal server error")
})
@PostMapping("/{productIdentifier}/resource-allocations")
ResponseEntity<ProductPSResourceAllocationResponseDto> createResourceAllocation(
@RequestHeader("Authorization") String accessToken,
@PathVariable("productIdentifier") UUID productIdentifier,
@RequestBody ProductPSResourceAllocationRequestDto allocationRequestDto);
@Operation(summary = "Update resource allocation", description = "Updates an existing resource allocation for a product.", requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(description = "Updated allocation details", required = true, content = @Content(schema = @Schema(implementation = ProductPSResourceAllocationRequestDto.class))), responses = {
@ApiResponse(responseCode = "200", description = "Allocation updated successfully"),
@ApiResponse(responseCode = "400", description = "Invalid allocation data"),
@ApiResponse(responseCode = "401", description = "Unauthorized"),
@ApiResponse(responseCode = "404", description = "Allocation not found"),
@ApiResponse(responseCode = "500", description = "Internal server error")
})
@PutMapping("/{productIdentifier}/resource-allocations/{allocationIdentifier}")
ResponseEntity<ProductPSResourceAllocationResponseDto> updateResourceAllocation(
@RequestHeader("Authorization") String accessToken,
@PathVariable("productIdentifier") UUID productIdentifier,
@PathVariable("allocationIdentifier") UUID allocationIdentifier,
@RequestBody ProductPSResourceAllocationRequestDto allocationRequestDto);
@Operation(summary = "Delete resource allocation", description = "Deletes a resource allocation from a product.", responses = {
@ApiResponse(responseCode = "204", description = "Allocation deleted successfully"),
@ApiResponse(responseCode = "401", description = "Unauthorized"),
@ApiResponse(responseCode = "404", description = "Allocation not found"),
@ApiResponse(responseCode = "500", description = "Internal server error")
})
@DeleteMapping("/{productIdentifier}/resource-allocations/{allocationIdentifier}")
ResponseEntity<Void> deleteResourceAllocation(
@RequestHeader("Authorization") String accessToken,
@PathVariable("productIdentifier") UUID productIdentifier,
@PathVariable("allocationIdentifier") UUID allocationIdentifier);
}

View File

@@ -0,0 +1,82 @@
package com.ikon.projectmanagement.api;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
import java.util.List;
import java.util.UUID;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import com.ikon.projectmanagement.dto.request.ProjectRequestDto;
import com.ikon.projectmanagement.dto.response.ProjectResponseDto;
import com.ikon.projectmanagement.dto.response.ProjectTimelineResponseDto;
@Tag(name = "Project APIs", description = "Project Management related APIs")
@RequestMapping("/api/v1/projects")
public interface ProjectApi {
@Operation(summary = "Create a new project", description = "Creates a new project and returns the created project details.", requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(description = "Project details", required = true, content = @Content(schema = @Schema(implementation = ProjectRequestDto.class))), responses = {
@ApiResponse(responseCode = "201", description = "Project created successfully"),
@ApiResponse(responseCode = "400", description = "Invalid project data"),
@ApiResponse(responseCode = "401", description = "Unauthorized"),
@ApiResponse(responseCode = "500", description = "Internal server error")
})
@PostMapping
ResponseEntity<ProjectResponseDto> createProject(
@RequestHeader("Authorization") String accessToken,
@RequestBody ProjectRequestDto projectDto);
@Operation(summary = "Get all projects", description = "Retrieves a list of all existing projects.", responses = {
@ApiResponse(responseCode = "200", description = "Projects retrieved successfully"),
@ApiResponse(responseCode = "401", description = "Unauthorized"),
@ApiResponse(responseCode = "500", description = "Internal server error")
})
@GetMapping
public ResponseEntity<List<ProjectResponseDto>> getAllProjects(
@RequestHeader("Authorization") String accessToken);
@Operation(summary = "Get project by Id", description = "Retrieves a project by its unique project ID.", responses = {
@ApiResponse(responseCode = "200", description = "Project retrieved successfully"),
@ApiResponse(responseCode = "401", description = "Unauthorized"),
@ApiResponse(responseCode = "404", description = "Project not found"),
@ApiResponse(responseCode = "500", description = "Internal server error")
})
@GetMapping("/{projectIdentifier}")
public ResponseEntity<ProjectResponseDto> getProjectByProjectIdentifier(
@RequestHeader("Authorization") String accessToken,
@PathVariable("projectIdentifier") UUID projectIdentifier);
@Operation(summary = "Update an existing project", description = "Updates the details of an existing project identified by its ID.", requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(description = "Updated project details", required = true, content = @Content(schema = @Schema(implementation = ProjectRequestDto.class))), responses = {
@ApiResponse(responseCode = "200", description = "Project updated successfully"),
@ApiResponse(responseCode = "400", description = "Invalid project data or ID provided"),
@ApiResponse(responseCode = "401", description = "Unauthorized"),
@ApiResponse(responseCode = "404", description = "Project not found"),
@ApiResponse(responseCode = "500", description = "Internal server error")
})
@PutMapping("/{projectIdentifier}")
ResponseEntity<ProjectResponseDto> updateProject(
@RequestHeader("Authorization") String accessToken,
@PathVariable("projectIdentifier") UUID projectIdentifier,
@RequestBody ProjectRequestDto projectDto);
@Operation(summary = "Get all active projects start and end dates", description = "Retrieves a list of all active projects with their start and end dates.", responses = {
@ApiResponse(responseCode = "200", description = "Projects retrieved successfully"),
@ApiResponse(responseCode = "401", description = "Unauthorized"),
@ApiResponse(responseCode = "500", description = "Internal server error")
})
@GetMapping("/active-projects-timeline")
public ResponseEntity<List<ProjectTimelineResponseDto>> getAllActiveProjectsTimeline(
@RequestHeader("Authorization") String accessToken);
}

View File

@@ -0,0 +1,84 @@
package com.ikon.projectmanagement.api;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
import java.util.List;
import java.util.UUID;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import com.ikon.projectmanagement.dto.request.RiskCreateRequestDto;
import com.ikon.projectmanagement.dto.response.RiskResponseDto;
@Tag(name = "Risk APIs", description = "Risk Management related APIs")
@RequestMapping("/api/v1/risks")
public interface RiskApi {
@Operation(summary = "Create a new risk", description = "Creates a new risk and returns the created risk details.", requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(description = "Risk details", required = true, content = @Content(schema = @Schema(implementation = RiskCreateRequestDto.class))), responses = {
@ApiResponse(responseCode = "201", description = "Risk created successfully"),
@ApiResponse(responseCode = "400", description = "Invalid risk data"),
@ApiResponse(responseCode = "401", description = "Unauthorized"),
@ApiResponse(responseCode = "500", description = "Internal server error")
})
@PostMapping
ResponseEntity<RiskResponseDto> createRisk(
@RequestHeader("Authorization") String accessToken,
@RequestBody RiskCreateRequestDto riskCreateRequestDto);
@Operation(summary = "Get all risks", description = "Retrieves a list of all existing risks.", responses = {
@ApiResponse(responseCode = "200", description = "Risks retrieved successfully"),
@ApiResponse(responseCode = "401", description = "Unauthorized"),
@ApiResponse(responseCode = "500", description = "Internal server error")
})
@GetMapping
ResponseEntity<List<RiskResponseDto>> getAllRisks(
@RequestHeader("Authorization") String accessToken);
@Operation(summary = "Get risk by Id", description = "Retrieves a risk by its unique risk ID.", responses = {
@ApiResponse(responseCode = "200", description = "Risk retrieved successfully"),
@ApiResponse(responseCode = "401", description = "Unauthorized"),
@ApiResponse(responseCode = "404", description = "Risk not found"),
@ApiResponse(responseCode = "500", description = "Internal server error")
})
@GetMapping("/{riskId}")
ResponseEntity<RiskResponseDto> getRiskById(
@RequestHeader("Authorization") String accessToken,
@PathVariable("riskId") UUID riskId);
@Operation(summary = "Update an existing risk", description = "Updates the details of an existing risk identified by its ID.", requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(description = "Updated risk details", required = true, content = @Content(schema = @Schema(implementation = RiskCreateRequestDto.class))), responses = {
@ApiResponse(responseCode = "200", description = "Risk updated successfully"),
@ApiResponse(responseCode = "400", description = "Invalid risk data or ID provided"),
@ApiResponse(responseCode = "401", description = "Unauthorized"),
@ApiResponse(responseCode = "404", description = "Risk not found"),
@ApiResponse(responseCode = "500", description = "Internal server error")
})
@PutMapping("/{riskId}")
ResponseEntity<RiskResponseDto> updateRisk(
@RequestHeader("Authorization") String accessToken,
@PathVariable("riskId") UUID riskId,
@RequestBody RiskCreateRequestDto riskCreateRequestDto);
@Operation(summary = "Get all risks by project", description = "Retrieves a list of all risks associated with a specific project.", responses = {
@ApiResponse(responseCode = "200", description = "Risks retrieved successfully"),
@ApiResponse(responseCode = "401", description = "Unauthorized"),
@ApiResponse(responseCode = "404", description = "Project not found"),
@ApiResponse(responseCode = "500", description = "Internal server error")
})
@GetMapping("/project/{projectIdentifier}")
ResponseEntity<List<RiskResponseDto>> getRisksByProject(
@RequestHeader("Authorization") String accessToken,
@PathVariable("projectIdentifier") String projectIdentifier);
}

View File

@@ -0,0 +1,45 @@
package com.ikon.projectmanagement.api;
import com.ikon.projectmanagement.dto.request.RoleRequestDto;
import com.ikon.projectmanagement.dto.response.RoleResponseDto;
import java.util.List;
import java.util.UUID;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseStatus;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
@Tag(name = "Role APIs", description = "APIs for managing local roles")
@RequestMapping("/api/v1/roles")
public interface RoleApi {
@Operation(summary = "Get all roles")
@GetMapping
ResponseEntity<List<RoleResponseDto>> getAllRoles();
@Operation(summary = "Get role by ID")
@GetMapping("/{id}")
ResponseEntity<RoleResponseDto> getRoleById(@PathVariable UUID id);
@Operation(summary = "Create a new role")
@PostMapping
@ResponseStatus(HttpStatus.CREATED)
ResponseEntity<RoleResponseDto> createRole(@RequestBody RoleRequestDto dto);
@Operation(summary = "Update an existing role")
@PutMapping("/{id}")
ResponseEntity<RoleResponseDto> updateRole(@PathVariable UUID id, @RequestBody RoleRequestDto dto);
@Operation(summary = "Delete a role")
@DeleteMapping("/{id}")
@ResponseStatus(HttpStatus.NO_CONTENT)
ResponseEntity<Void> deleteRole(@PathVariable UUID id);
}

View File

@@ -0,0 +1,49 @@
package com.ikon.projectmanagement.api;
import com.ikon.projectmanagement.dto.request.ScheduleRequestDto;
import com.ikon.projectmanagement.dto.response.ScheduleResponseDto;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.UUID;
@Tag(name = "Schedule APIs", description = "Schedule management APIs for a project")
@RequestMapping("/api/v1/projects")
public interface ScheduleApi {
@Operation(summary = "Save schedule", description = "Replaces the full schedule (tasks + dependencies) for a project. Removed tasks are automatically deleted.", responses = {
@ApiResponse(responseCode = "200", description = "Schedule saved successfully"),
@ApiResponse(responseCode = "401", description = "Unauthorized"),
@ApiResponse(responseCode = "404", description = "Project not found"),
@ApiResponse(responseCode = "500", description = "Internal server error")
})
@PutMapping("/{projectIdentifier}/schedules")
ResponseEntity<ScheduleResponseDto> saveSchedule(
@RequestHeader("Authorization") String accessToken,
@PathVariable("projectIdentifier") UUID projectIdentifier,
@RequestBody ScheduleRequestDto scheduleRequestDto);
@Operation(summary = "Get schedule", description = "Retrieves the current schedule (tasks + dependencies) for a project.", responses = {
@ApiResponse(responseCode = "200", description = "Schedule retrieved successfully"),
@ApiResponse(responseCode = "401", description = "Unauthorized"),
@ApiResponse(responseCode = "404", description = "Project not found"),
@ApiResponse(responseCode = "500", description = "Internal server error")
})
@GetMapping("/{projectIdentifier}/schedules")
ResponseEntity<ScheduleResponseDto> getSchedule(
@RequestHeader("Authorization") String accessToken,
@PathVariable("projectIdentifier") UUID projectIdentifier);
@Operation(summary = "Get all schedules", description = "Retrieves schedules for all projects under the current account.", responses = {
@ApiResponse(responseCode = "200", description = "Schedules retrieved successfully"),
@ApiResponse(responseCode = "401", description = "Unauthorized"),
@ApiResponse(responseCode = "500", description = "Internal server error")
})
@GetMapping("/schedules")
ResponseEntity<List<ScheduleResponseDto>> getAllSchedules(
@RequestHeader("Authorization") String accessToken);
}

View File

@@ -0,0 +1,37 @@
package com.ikon.projectmanagement.api;
import com.ikon.projectmanagement.dto.response.WorkingDaysResponseDto;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
@Tag(name = "Working Day APIs", description = "APIs for managing local working days")
@RequestMapping("/api/v1/working-days")
public interface WorkingDayApi {
@Operation(summary = "Get all working days configurations", description = "Fetches all working days configurations.", responses = {
@ApiResponse(responseCode = "200", description = "Working days list fetched successfully"),
@ApiResponse(responseCode = "500", description = "Internal server error")
})
@GetMapping
ResponseEntity<Page<WorkingDaysResponseDto>> getAllWorkingDays(
@RequestHeader("Authorization") String accessToken,
Pageable pageable);
@Operation(summary = "Get working days by year", description = "Fetches working days configuration by year.", responses = {
@ApiResponse(responseCode = "200", description = "Working days fetched successfully"),
@ApiResponse(responseCode = "404", description = "Working days not found"),
@ApiResponse(responseCode = "500", description = "Internal server error")
})
@GetMapping("/{year}")
ResponseEntity<WorkingDaysResponseDto> getWorkingDaysByYear(
@RequestHeader("Authorization") String accessToken,
@PathVariable String year);
}

View File

@@ -0,0 +1,17 @@
package com.ikon.projectmanagement.dto.request;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class ActionItemDTO {
private String item;
private String responsible;
private String dueDate;
}

View File

@@ -0,0 +1,15 @@
package com.ikon.projectmanagement.dto.request;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;
import java.util.List;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class ActionsWrapperDTO {
private List<ActionItemDTO> actions;
}

View File

@@ -0,0 +1,15 @@
package com.ikon.projectmanagement.dto.request;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class AgendaItemDTO {
private String item;
private String owner;
}

View File

@@ -0,0 +1,15 @@
package com.ikon.projectmanagement.dto.request;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;
import java.util.List;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class AgendaWrapperDTO {
private List<AgendaItemDTO> agenda;
}

View File

@@ -0,0 +1,17 @@
package com.ikon.projectmanagement.dto.request;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class AttendeeDTO {
private String name;
private String role;
private String contact;
}

View File

@@ -0,0 +1,15 @@
package com.ikon.projectmanagement.dto.request;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;
import java.util.List;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class AttendeesWrapperDTO {
private List<AttendeeDTO> attendees;
}

View File

@@ -0,0 +1,15 @@
package com.ikon.projectmanagement.dto.request;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;
import java.util.List;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class DecisionsWrapperDTO {
private List<String> decisions;
}

View File

@@ -0,0 +1,20 @@
package com.ikon.projectmanagement.dto.request;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class EmployeeRequestDto {
private String empId;
private String name;
private String email;
private String organizationEmail;
private String role;
private String grade;
private Boolean active;
}

View File

@@ -0,0 +1,19 @@
package com.ikon.projectmanagement.dto.request;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.math.BigDecimal;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class FxRateDto {
private String fromCurrency;
private String toCurrency;
private BigDecimal rate;
private String effectiveDate;
}

View File

@@ -0,0 +1,18 @@
package com.ikon.projectmanagement.dto.request;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.UUID;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class GradeRequestDto {
private UUID id;
private UUID accountId;
private String grade;
}

View File

@@ -0,0 +1,17 @@
package com.ikon.projectmanagement.dto.request;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class ImportDataRequestDto {
private Integer page;
private Integer size;
private String filterBy;
private String filterValue;
}

View File

@@ -0,0 +1,47 @@
package com.ikon.projectmanagement.dto.request;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.UUID;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class IssueCreateRequestDto {
private String issueTitle;
private Integer issueProbability;
private BigDecimal grossIssueValue;
private BigDecimal probableIssueValue;
private BigDecimal probableIssueValueInUSD;
private String issueImpact;
private String issueOwner;
private String issueDescription;
private String mitigationAction;
private UUID projectIdentifier;
private Boolean financialIssue;
private LocalDateTime issueCreatedDate;
private String issueOptionsSelectId;
private String issueStatus;
private Integer issueAge;
private String effectedSprintId;
}

View File

@@ -0,0 +1,27 @@
package com.ikon.projectmanagement.dto.request;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
public class MeetingDetailsDTO {
private String title;
private String projectName;
private String place;
private String date;
private String time;
private String duration;
private String calledBy;
}

View File

@@ -0,0 +1,30 @@
package com.ikon.projectmanagement.dto.request;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.UUID;
import lombok.AllArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class MeetingRequestDTO {
private MeetingDetailsDTO meeting;
private AttendeesWrapperDTO attendees;
private AgendaWrapperDTO agenda;
private DecisionsWrapperDTO decisions;
private ActionsWrapperDTO actions;
private OthersDTO others;
private UUID projectIdentifier;
private String status;
}

View File

@@ -0,0 +1,13 @@
package com.ikon.projectmanagement.dto.request;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class OthersDTO {
private String notes;
}

View File

@@ -0,0 +1,22 @@
package com.ikon.projectmanagement.dto.request;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ProductExpenseRequestDto {
private String expenseName;
private String location;
private String currency;
private Double cost;
private Integer quantity;
private Double totalCost;
private String remarks;
}

View File

@@ -0,0 +1,35 @@
package com.ikon.projectmanagement.dto.request;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import com.ikon.projectmanagement.dto.response.ProductExpenseResponseDto;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ProductOfProjectRequestDto {
private UUID projectIdentifier;
private String projectName;
private UUID projectManager;
private UUID accountId;
private UUID leadIdentifier;
private String productStatus;
private String projectStatus;
private String productType;
private String productDescription;
private Double discountPercent;
private Map<UUID, ProductExpenseResponseDto> expenseDetails;
private List<ProductPSResourceAllocationRequestDto> resourceDataWithAllocation;
}

View File

@@ -0,0 +1,25 @@
package com.ikon.projectmanagement.dto.request;
import java.util.Map;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ProductPSResourceAllocationRequestDto {
private String resourceType;
private String role;
private Integer gradeId;
private String employeeName;
private String taskName;
private String resourceId;
private Long taskId;
private Map<String, Double> allocation;
private Map<String, Map<String, Object>> detailedAllocation;
}

View File

@@ -0,0 +1,51 @@
package com.ikon.projectmanagement.dto.request;
import lombok.*;
import java.time.LocalDate;
import java.util.*;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ProjectRequestDto {
private UUID projectManager;
private String projectName;
private String projectStatus;
private String projectNumber;
private String parentProjectNo;
private String contractNumber;
private String projectClient;
private String projectCity;
private String projectCountry;
private String currency;
private String projectImage;
private String contractUpload;
private String source;
private String productType;
private String expenses;
private String formattedActualRevenueIncludingVAT_deal;
private Boolean isCompleted;
private Boolean groupNotExist;
private Boolean isDebtRevenue_deal;
private String projectDescription;
private UUID updatedBy;
private UUID projectManagerDelegates;
private LocalDate projectStartDate;
private LocalDate contractedStartDate;
private LocalDate contractedEndDate;
private List<UUID> projectTeam;
private List<UUID> projectTeamUnderProjectManager;
private List<UUID> projectTeamUnderProjectManagerDelegates;
private String groupAssigneesEditStr;
private String groupAssigneesViewStr;
private Map<String, Object> participants;
private Map<String, Object> contractedProductIdentifierWiseDataObj;
}

View File

@@ -0,0 +1,45 @@
package com.ikon.projectmanagement.dto.request;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.UUID;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class RiskCreateRequestDto {
private String riskTitle;
private Integer riskProbability;
private BigDecimal grossRiskValue;
private BigDecimal probableRiskValue;
private BigDecimal probableRiskValueInUSD;
private String riskImpact;
private String riskOwner;
private String riskDescription;
private UUID projectIdentifier;
private Boolean financialRisk;
private LocalDateTime riskCreatedDate;
private String riskOptionsSelectId;
private String riskStatus;
private Integer riskAge;
private String effectedSprintId;
}

View File

@@ -0,0 +1,17 @@
package com.ikon.projectmanagement.dto.request;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.UUID;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class RoleRequestDto {
private UUID id;
private String role;
}

View File

@@ -0,0 +1,14 @@
package com.ikon.projectmanagement.dto.request;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class ScheduleDependencyDto {
private Long id;
private Long predecessorId;
private Integer dependencyType;
}

View File

@@ -0,0 +1,18 @@
package com.ikon.projectmanagement.dto.request;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.ArrayList;
import java.util.List;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class ScheduleGroupDto {
private String id;
private String groupName;
private List<Long> taskIds = new ArrayList<>();
private String color;
}

View File

@@ -0,0 +1,17 @@
package com.ikon.projectmanagement.dto.request;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
import java.util.Map;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class ScheduleRequestDto {
private List<ScheduleTaskDto> task;
private List<ScheduleDependencyDto> dependency;
private Map<String, ScheduleGroupDto> group;
}

View File

@@ -0,0 +1,23 @@
package com.ikon.projectmanagement.dto.request;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class ScheduleTaskDto {
private Long id;
private Long parentId;
private String taskName;
private Double taskDuration;
private String taskPredecessor;
private Integer dependencyType;
private String taskColour;
private Double delayDuration;
private String taskDescription;
private String taskStart;
private String taskEnd;
private Boolean milestoneTask;
}

View File

@@ -0,0 +1,22 @@
package com.ikon.projectmanagement.dto.request;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class WorkflowTransitionRequestDto {
/**
* The target productStatus string to transition to.
* e.g. "Schedule Submitted From Product",
* "Submitted Resources and Expenses For Product",
* "Closed",
* "Recall Product Created from Schedule", etc.
*/
private String targetStatus;
}

View File

@@ -0,0 +1,16 @@
package com.ikon.projectmanagement.dto.request;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class WorkingDayDto {
private String year;
private String month;
private String workingDays;
}

View File

@@ -0,0 +1,16 @@
package com.ikon.projectmanagement.dto.response;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class DashboardWidgetsResponseDto {
private Long totalProjects;
private Long totalIssues;
private Long totalRisksCount;
}

View File

@@ -0,0 +1,26 @@
package com.ikon.projectmanagement.dto.response;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.UUID;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class EmployeeResponseDto {
private String empId;
private UUID accountId;
private String name;
private String email;
private String organizationEmail;
private String role;
private String grade;
private Boolean active;
private String highestQualification;
private String joiningDate;
private String confirmationDate;
}

View File

@@ -0,0 +1,12 @@
package com.ikon.projectmanagement.dto.response;
import lombok.Data;
@Data
public class FxRateDetailsDto {
private String id;
private String currency;
private Double fxRate;
private Boolean activeStatus;
private String year;
}

View File

@@ -0,0 +1,22 @@
package com.ikon.projectmanagement.dto.response;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.math.BigDecimal;
import java.util.UUID;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class FxRateDto {
private UUID id;
private UUID accountId;
private String fromCurrency;
private String toCurrency;
private BigDecimal rate;
private String effectiveDate;
}

View File

@@ -0,0 +1,13 @@
package com.ikon.projectmanagement.dto.response;
import java.util.Map;
import java.util.UUID;
import lombok.Data;
@Data
public class FxRateResponseDto {
private UUID fxRateId;
private UUID accountIdentifier;
private Map<String, Map<String, FxRateDetailsDto>> fxRateDetails;
}

View File

@@ -0,0 +1,18 @@
package com.ikon.projectmanagement.dto.response;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.UUID;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class GradeResponseDto {
private UUID id;
private UUID accountId;
private String grade;
}

View File

@@ -0,0 +1,49 @@
package com.ikon.projectmanagement.dto.response;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.UUID;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class IssueResponseDto {
private UUID issueId;
private String issueTitle;
private Integer issueProbability;
private BigDecimal grossIssueValue;
private BigDecimal probableIssueValue;
private BigDecimal probableIssueValueInUSD;
private String issueImpact;
private String issueOwner;
private String issueDescription;
private String mitigationAction;
private UUID projectIdentifier;
private Boolean financialIssue;
private LocalDateTime issueCreatedDate;
private String issueOptionsSelectId;
private String issueStatus;
private Integer issueAge;
private String effectedSprintId;
}

View File

@@ -0,0 +1,37 @@
package com.ikon.projectmanagement.dto.response;
import com.ikon.projectmanagement.dto.request.*;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;
import java.time.LocalDateTime;
import java.util.UUID;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class MeetingResponseDTO {
private UUID id;
private MeetingDetailsDTO meeting;
private AttendeesWrapperDTO attendees;
private AgendaWrapperDTO agenda;
private DecisionsWrapperDTO decisions;
private ActionsWrapperDTO actions;
private OthersDTO others;
private UUID projectIdentifier;
private String status;
private LocalDateTime createdAt;
private LocalDateTime updatedAt;
}

View File

@@ -0,0 +1,25 @@
package com.ikon.projectmanagement.dto.response;
import java.util.UUID;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ProductExpenseResponseDto {
private UUID expenseIdentifier;
private String expenseName;
private String location;
private String currency;
private Double cost;
private Integer quantity;
private Double totalCost;
private String remarks;
}

View File

@@ -0,0 +1,40 @@
package com.ikon.projectmanagement.dto.response;
import java.util.Map;
import java.util.UUID;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ProductOfProjectResponseDto {
private UUID productIdentifier;
private UUID projectIdentifier;
private String projectName;
private UUID projectManager;
private UUID accountId;
private UUID leadIdentifier;
private String productStatus;
private String projectStatus;
private String productType;
private String productDescription;
private Double discountPercent;
private String createdOn;
private UUID createdBy;
private UUID updatedBy;
private String updatedOn;
private Map<UUID, ProductExpenseResponseDto> expenseDetails;
private ScheduleResponseDto scheduleData;
}

View File

@@ -0,0 +1,27 @@
package com.ikon.projectmanagement.dto.response;
import java.util.Map;
import java.util.UUID;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ProductPSResourceAllocationResponseDto {
private UUID id;
private String resourceType;
private String role;
private Integer gradeId;
private String employeeName;
private String taskName;
private String resourceId;
private Long taskId;
private Map<String, Double> allocation;
private Map<String, Map<String, Object>> detailedAllocation;
}

View File

@@ -0,0 +1,63 @@
package com.ikon.projectmanagement.dto.response;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDate;
import java.util.List;
import java.util.Map;
import java.util.UUID;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ProjectResponseDto {
private UUID projectIdentifier;
private UUID projectManager;
private String projectName;
private String projectStatus;
private String projectNumber;
private String parentProjectNo;
private String contractNumber;
private String projectClient;
private String projectCity;
private String projectCountry;
private String currency;
private String projectImage;
private String contractUpload;
private String source;
private String productType;
private String expenses;
private String formattedActualRevenueIncludingVAT_deal;
private Boolean isCompleted;
private Boolean groupNotExist;
private Boolean isDebtRevenue_deal;
private String projectDescription;
private UUID createdById;
private UUID updatedBy;
private UUID projectManagerDelegates;
private LocalDate projectStartDate;
private LocalDate contractedStartDate;
private LocalDate contractedEndDate;
private LocalDate createdOn;
private LocalDate updatedOn;
private List<UUID> projectTeam;
private List<UUID> projectTeamUnderProjectManager;
private List<UUID> projectTeamUnderProjectManagerDelegates;
private String groupAssigneesEditStr;
private String groupAssigneesViewStr;
private Map<String, Object> participants;
private Map<String, Object> contractedProductIdentifierWiseDataObj;
private UUID productIdentifier;
}

View File

@@ -0,0 +1,19 @@
package com.ikon.projectmanagement.dto.response;
import java.util.UUID;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class ProjectTimelineResponseDto {
private UUID projectIdentifier;
private String projectName;
private String startDate;
private String endDate;
}

View File

@@ -0,0 +1,46 @@
package com.ikon.projectmanagement.dto.response;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.UUID;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class RiskResponseDto {
private UUID riskIdentifier;
private String riskTitle;
private Integer riskProbability;
private BigDecimal grossRiskValue;
private BigDecimal probableRiskValue;
private BigDecimal probableRiskValueInUSD;
private String riskImpact;
private String riskOwner;
private String riskDescription;
private UUID projectIdentifier;
private Boolean financialRisk;
private LocalDateTime riskCreatedDate;
private String riskOptionsSelectId;
private String riskStatus;
private Integer riskAge;
private String effectedSprintId;
}

View File

@@ -0,0 +1,18 @@
package com.ikon.projectmanagement.dto.response;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.UUID;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class RoleResponseDto {
private UUID id;
private UUID accountId;
private String role;
}

View File

@@ -0,0 +1,23 @@
package com.ikon.projectmanagement.dto.response;
import com.ikon.projectmanagement.dto.request.ScheduleDependencyDto;
import com.ikon.projectmanagement.dto.request.ScheduleGroupDto;
import com.ikon.projectmanagement.dto.request.ScheduleTaskDto;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
import java.util.Map;
import java.util.UUID;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class ScheduleResponseDto {
private UUID projectIdentifier;
private UUID productIdentifier;
private List<ScheduleTaskDto> task;
private List<ScheduleDependencyDto> dependency;
private Map<String, ScheduleGroupDto> group;
}

View File

@@ -0,0 +1,15 @@
package com.ikon.projectmanagement.dto.response;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class StatusWiseProjectResponseData {
private String status;
private Long projectCount;
}

View File

@@ -0,0 +1,20 @@
package com.ikon.projectmanagement.dto.response;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.UUID;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class WorkingDayDto {
private UUID id;
private UUID accountId;
private String year;
private String month;
private String workingDays;
}

View File

@@ -0,0 +1,12 @@
package com.ikon.projectmanagement.dto.response;
import lombok.Data;
@Data
public class WorkingDaysMonthDto {
private String year;
private String month;
private Integer workingDays;
}

View File

@@ -0,0 +1,12 @@
package com.ikon.projectmanagement.dto.response;
import lombok.Data;
import java.util.Map;
import java.util.UUID;
@Data
public class WorkingDaysResponseDto {
private UUID workingId;
private UUID accountIdentifier;
private Map<String, Map<String, WorkingDaysMonthDto>> workingDaysDetails;
}

View File

@@ -0,0 +1,128 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.ikon.projectmanagement</groupId>
<artifactId>projectmanagement</artifactId>
<version>1.0.0</version>
</parent>
<artifactId>projectmanagement-server</artifactId>
<repositories>
<repository>
<id>confluent</id>
<url>https://packages.confluent.io/maven/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>com.ikon</groupId>
<artifactId>ikon-sdk</artifactId>
<version>${ikon.sdk.version}</version>
</dependency>
<dependency>
<groupId>com.ikon.projectmanagement</groupId>
<artifactId>projectmanagement-client</artifactId>
<version>${projectmanagement.version}</version>
</dependency>
<dependency>
<groupId>com.ikon</groupId>
<artifactId>ikon-client</artifactId>
<version>${ikon.sdk.version}</version>
</dependency>
<!-- <dependency>
<groupId>com.ikon</groupId>
<artifactId>ikon-processmanagement</artifactId>
<version>${ikon.sdk.version}</version>
</dependency> -->
<!-- <dependency>
<groupId>com.ikon</groupId>
<artifactId>ikon-job-executor</artifactId>
<version>${ikon.sdk.version}</version>
</dependency> -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.modelmapper</groupId>
<artifactId>modelmapper</artifactId>
<version>3.2.2</version>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka</artifactId>
</dependency>
<dependency>
<groupId>io.confluent</groupId>
<artifactId>kafka-avro-serializer</artifactId>
<version>${avro-serializer.version}</version>
</dependency>
<dependency>
<groupId>com.ikon</groupId>
<artifactId>ikon-connector</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
<!-- Attach Javadoc JAR -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,42 @@
package com.ikon.projectmanagement;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.actuate.autoconfigure.cassandra.CassandraHealthContributorAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import com.ikon.autoconfigure.annotation.EnableIkonSdk;
import com.ikon.sdk.config.IkonSdkConfig;
@EntityScan(basePackages = {
"com.ikon.projectmanagement.entity",
})
@EnableJpaRepositories(basePackages = {
"com.ikon.projectmanagement.repository",
})
@EnableFeignClients(basePackages = {
"com.ikon.client",
})
@SpringBootApplication(scanBasePackages = {
"com.ikon.projectmanagement",
}, exclude = {
CassandraAutoConfiguration.class,
CassandraHealthContributorAutoConfiguration.class
})
@EnableJpaAuditing
@EnableIkonSdk(configuration = IkonSdkConfig.class)
public class ProjectManagementApplication {
public static void main(String[] args) {
SpringApplication.run(ProjectManagementApplication.class, args);
}
}

View File

@@ -0,0 +1,15 @@
package com.ikon.projectmanagement.config;
import org.modelmapper.ModelMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class ModelMapperConfig {
@Bean
ModelMapper modelMapper() {
return new ModelMapper();
}
}

View File

@@ -0,0 +1,13 @@
package com.ikon.projectmanagement.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
@Configuration
public class RestTemplateConfigs {
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
}

View File

@@ -0,0 +1,67 @@
package com.ikon.projectmanagement.config;
import java.util.Arrays;
import java.util.List;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.convert.converter.Converter;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.oauth2.jwt.Jwt;
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken;
import org.springframework.security.oauth2.server.resource.authentication.JwtGrantedAuthoritiesConverter;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import com.ikon.webservice.security.IkonJwtTokenConverter;
@Configuration
@EnableWebSecurity
@EnableMethodSecurity
public class SecurityConfig {
private Converter<Jwt, JwtAuthenticationToken> ikonJwtTokenConverter = new IkonJwtTokenConverter(
new JwtGrantedAuthoritiesConverter());
@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.cors(cors -> cors.configurationSource(corsConfigurationSource())) // Enable CORS
.csrf(AbstractHttpConfigurer::disable)
.httpBasic(AbstractHttpConfigurer::disable)
.authorizeHttpRequests((authorize) -> {
authorize
.requestMatchers("/actuator/health", "/actuator/health/**").permitAll()
.requestMatchers(HttpMethod.OPTIONS, "/**").permitAll()
.anyRequest().authenticated();
})
.oauth2ResourceServer((oauth2) -> {
oauth2.jwt((jwt) -> jwt.jwtAuthenticationConverter(ikonJwtTokenConverter));
});
return http.build();
}
@Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(List.of("http://localhost:3000"));
configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS"));
configuration.setAllowedHeaders(List.of("*"));
configuration.setAllowCredentials(true);
configuration.setMaxAge(3600L);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
}

View File

@@ -0,0 +1,31 @@
package com.ikon.projectmanagement.controller;
import java.util.List;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RestController;
import com.ikon.projectmanagement.api.DashboardApi;
import com.ikon.projectmanagement.dto.response.DashboardWidgetsResponseDto;
import com.ikon.projectmanagement.dto.response.StatusWiseProjectResponseData;
import com.ikon.projectmanagement.service.DashboardService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@RestController
@RequiredArgsConstructor
@Slf4j
public class DashboardController implements DashboardApi {
private final DashboardService dashboardService;
@Override
public ResponseEntity<DashboardWidgetsResponseDto> getWidgetsData(String accessToken) {
DashboardWidgetsResponseDto widgetsData = dashboardService.getDashboardWidgetsData();
return ResponseEntity.ok(widgetsData);
}
@Override
public ResponseEntity<List<StatusWiseProjectResponseData>> getStatusWiseProjectData(String accessToken) {
List<StatusWiseProjectResponseData> statusWiseData = dashboardService.getStatusWiseProjectData();
return ResponseEntity.ok(statusWiseData);
}
}

View File

@@ -0,0 +1,63 @@
package com.ikon.projectmanagement.controller;
import com.ikon.projectmanagement.api.EmployeeApi;
import com.ikon.projectmanagement.dto.request.EmployeeRequestDto;
import com.ikon.projectmanagement.dto.response.EmployeeResponseDto;
import com.ikon.projectmanagement.service.EmployeeService;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequiredArgsConstructor
public class EmployeeController implements EmployeeApi {
private final EmployeeService employeeService;
@Override
public ResponseEntity<List<EmployeeResponseDto>> getAllEmployees() {
return ResponseEntity.ok(employeeService.getAllEmployees());
}
@Override
public ResponseEntity<EmployeeResponseDto> getEmployeeById(String id) {
try {
EmployeeResponseDto employee = employeeService.getEmployeeById(id);
return ResponseEntity.ok(employee);
} catch (RuntimeException e) {
return ResponseEntity.notFound().build();
}
}
@Override
public ResponseEntity<EmployeeResponseDto> createEmployee(EmployeeRequestDto dto) {
try {
EmployeeResponseDto createdEmployee = employeeService.createEmployee(dto);
return ResponseEntity.status(HttpStatus.CREATED).body(createdEmployee);
} catch (RuntimeException e) {
return ResponseEntity.badRequest().build();
}
}
@Override
public ResponseEntity<EmployeeResponseDto> updateEmployee(String id, EmployeeRequestDto dto) {
try {
EmployeeResponseDto updatedEmployee = employeeService.updateEmployee(id, dto);
return ResponseEntity.ok(updatedEmployee);
} catch (RuntimeException e) {
return ResponseEntity.notFound().build();
}
}
@Override
public ResponseEntity<Void> deleteEmployee(String id) {
try {
employeeService.deleteEmployee(id);
return ResponseEntity.noContent().build();
} catch (RuntimeException e) {
return ResponseEntity.notFound().build();
}
}
}

View File

@@ -0,0 +1,32 @@
package com.ikon.projectmanagement.controller;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import com.ikon.projectmanagement.api.FxRateApi;
import com.ikon.projectmanagement.dto.response.FxRateResponseDto;
import com.ikon.projectmanagement.service.FxRateService;
@RestController
@RequiredArgsConstructor
public class FxRateController implements FxRateApi {
private final FxRateService fxRateService;
@Override
public ResponseEntity<Page<FxRateResponseDto>> getAllFxRates(
@RequestHeader("Authorization") String accessToken,
Pageable pageable) {
return ResponseEntity.ok(fxRateService.getAllFxRates(pageable));
}
public ResponseEntity<FxRateResponseDto> getFxRateByYear(
@RequestHeader("Authorization") String accessToken,
@PathVariable String year) {
return ResponseEntity.ok(fxRateService.getFxRateByYear(year));
}
}

View File

@@ -0,0 +1,64 @@
package com.ikon.projectmanagement.controller;
import com.ikon.projectmanagement.api.GradeApi;
import com.ikon.projectmanagement.dto.request.GradeRequestDto;
import com.ikon.projectmanagement.dto.response.GradeResponseDto;
import com.ikon.projectmanagement.service.GradeService;
import java.util.List;
import java.util.UUID;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequiredArgsConstructor
public class GradeController implements GradeApi {
private final GradeService gradeService;
@Override
public ResponseEntity<List<GradeResponseDto>> getAllGrades() {
return ResponseEntity.ok(gradeService.getAllGrades());
}
@Override
public ResponseEntity<GradeResponseDto> getGradeById(UUID id) {
try {
GradeResponseDto grade = gradeService.getGradeById(id);
return ResponseEntity.ok(grade);
} catch (RuntimeException e) {
return ResponseEntity.notFound().build();
}
}
@Override
public ResponseEntity<GradeResponseDto> createGrade(GradeRequestDto dto) {
try {
GradeResponseDto createdGrade = gradeService.createGrade(dto);
return ResponseEntity.status(HttpStatus.CREATED).body(createdGrade);
} catch (RuntimeException e) {
return ResponseEntity.badRequest().build();
}
}
@Override
public ResponseEntity<GradeResponseDto> updateGrade(UUID id, GradeRequestDto dto) {
try {
GradeResponseDto updatedGrade = gradeService.updateGrade(id, dto);
return ResponseEntity.ok(updatedGrade);
} catch (RuntimeException e) {
return ResponseEntity.notFound().build();
}
}
@Override
public ResponseEntity<Void> deleteGrade(UUID id) {
try {
gradeService.deleteGrade(id);
return ResponseEntity.noContent().build();
} catch (RuntimeException e) {
return ResponseEntity.notFound().build();
}
}
}

View File

@@ -0,0 +1,26 @@
package com.ikon.projectmanagement.controller;
import java.util.List;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RestController;
import com.ikon.projectmanagement.api.ImportEmployeeApi;
import com.ikon.projectmanagement.dto.response.EmployeeResponseDto;
import com.ikon.projectmanagement.service.ImportEmployeeService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@RestController
@RequiredArgsConstructor
@Slf4j
public class ImportEmployeeController implements ImportEmployeeApi {
private final ImportEmployeeService importEmployeeService;
@Override
public ResponseEntity<List<EmployeeResponseDto>> fetchAllEmployees(String accessToken) {
return ResponseEntity.ok(importEmployeeService.importEmployees(accessToken));
}
}

Some files were not shown because too many files have changed in this diff Show More