Переглянути джерело

Add project creation

tags/Baseline_30082024_BACKEND_UAT
Wayne 1 рік тому
джерело
коміт
de4435fcee
18 змінених файлів з 312 додано та 9 видалено
  1. +1
    -1
      README.md
  2. +20
    -0
      src/main/java/com/ffii/tsms/modules/data/service/CustomerService.kt
  3. +13
    -0
      src/main/java/com/ffii/tsms/modules/data/service/StaffsService.kt
  4. +16
    -0
      src/main/java/com/ffii/tsms/modules/data/web/StaffsController.kt
  5. +5
    -1
      src/main/java/com/ffii/tsms/modules/project/entity/Milestone.kt
  6. +26
    -0
      src/main/java/com/ffii/tsms/modules/project/entity/MilestonePayment.kt
  7. +1
    -1
      src/main/java/com/ffii/tsms/modules/project/entity/MilestoneRepository.kt
  8. +8
    -0
      src/main/java/com/ffii/tsms/modules/project/entity/Project.kt
  9. +15
    -0
      src/main/java/com/ffii/tsms/modules/project/entity/ProjectCategory.kt
  10. +6
    -0
      src/main/java/com/ffii/tsms/modules/project/entity/ProjectCategoryRepository.kt
  11. +1
    -1
      src/main/java/com/ffii/tsms/modules/project/entity/ProjectTask.kt
  12. +43
    -0
      src/main/java/com/ffii/tsms/modules/project/service/ProjectsService.kt
  13. +18
    -5
      src/main/java/com/ffii/tsms/modules/project/web/ProjectsController.kt
  14. +44
    -0
      src/main/java/com/ffii/tsms/modules/project/web/models/NewProjectRequest.kt
  15. +41
    -0
      src/main/resources/db/changelog/changes/20240318_01_wayne/01_salary_data.sql
  16. +35
    -0
      src/main/resources/db/changelog/changes/20240318_01_wayne/02_mock_team_leads.sql
  17. +12
    -0
      src/main/resources/db/changelog/changes/20240318_01_wayne/03_project_categories.sql
  18. +7
    -0
      src/main/resources/db/changelog/changes/20240318_01_wayne/04_update_project.sql

+ 1
- 1
README.md Переглянути файл

@@ -45,5 +45,5 @@ This project can also be run using gradle.
### Running the application
After creating the table in MySQL, run
```shell
SPRING_PROFILES_ACTIVE=db-local,ldap-local ./gradlew bootRun
./gradlew bootRun --args='--spring.profiles.active=db-local'
```

+ 20
- 0
src/main/java/com/ffii/tsms/modules/data/service/CustomerService.kt Переглянути файл

@@ -0,0 +1,20 @@
package com.ffii.tsms.modules.data.service

import com.ffii.tsms.modules.data.entity.Customer
import com.ffii.tsms.modules.data.entity.CustomerRepository
import org.springframework.stereotype.Service

@Service
class CustomerService(private val customerRepository: CustomerRepository) {
fun saveCustomer(name: String, code: String, email: String, phone: String, contactName: String): Customer {
return customerRepository.save(
Customer().apply {
this.name = name
this.email = email
this.phone = phone
this.code = code
this.contactName = contactName
}
)
}
}

+ 13
- 0
src/main/java/com/ffii/tsms/modules/data/service/StaffsService.kt Переглянути файл

@@ -0,0 +1,13 @@
package com.ffii.tsms.modules.data.service
import com.ffii.tsms.modules.data.entity.Staff
import com.ffii.tsms.modules.data.entity.StaffRepository
import org.springframework.stereotype.Service
@Service
class StaffsService(private val staffRepository: StaffRepository) {
fun getTeamLeads(): List<Staff> {
// TODO: Replace with actual logic and make a projection instead of returning all fields
return staffRepository.findAll()
}
}

+ 16
- 0
src/main/java/com/ffii/tsms/modules/data/web/StaffsController.kt Переглянути файл

@@ -0,0 +1,16 @@
package com.ffii.tsms.modules.data.web
import com.ffii.tsms.modules.data.entity.Staff
import com.ffii.tsms.modules.data.service.StaffsService
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
@RestController
@RequestMapping("/staffs")
class StaffsController(private val staffsService: StaffsService) {
@GetMapping("/teamLeads")
fun teamLeads(): List<Staff> {
return staffsService.getTeamLeads()
}
}

src/main/java/com/ffii/tsms/modules/project/entity/PaymentMilestone.kt → src/main/java/com/ffii/tsms/modules/project/entity/Milestone.kt Переглянути файл

@@ -3,12 +3,13 @@ package com.ffii.tsms.modules.project.entity
import com.ffii.core.entity.IdEntity
import jakarta.persistence.Column
import jakarta.persistence.Entity
import jakarta.persistence.OneToMany
import jakarta.persistence.Table
import jakarta.validation.constraints.NotNull

@Entity
@Table(name = "milestone")
open class PaymentMilestone : IdEntity<Long>() {
open class Milestone : IdEntity<Long>() {
@NotNull
@Column(name = "name")
open var name: String? = null
@@ -16,4 +17,7 @@ open class PaymentMilestone : IdEntity<Long>() {
@NotNull
@Column(name = "description")
open var description: String? = null

@OneToMany(mappedBy = "milestone", orphanRemoval = true)
open var milestonePayments: MutableList<MilestonePayment> = mutableListOf()
}

+ 26
- 0
src/main/java/com/ffii/tsms/modules/project/entity/MilestonePayment.kt Переглянути файл

@@ -0,0 +1,26 @@
package com.ffii.tsms.modules.project.entity

import com.ffii.core.entity.IdEntity
import jakarta.persistence.*
import jakarta.validation.constraints.NotNull
import java.time.LocalDate

@Entity
@Table(name = "milestone_payment")
open class MilestonePayment : IdEntity<Long>() {
@NotNull
@Column(name = "date")
open var date: LocalDate? = null

@NotNull
@Column(name = "amount")
open var amount: Double? = null

@NotNull
@Column(name = "description")
open var description: String? = null

@ManyToOne
@JoinColumn(name = "milestone_id")
open var milestone: Milestone? = null
}

src/main/java/com/ffii/tsms/modules/project/entity/PaymentMilestoneRepository.kt → src/main/java/com/ffii/tsms/modules/project/entity/MilestoneRepository.kt Переглянути файл

@@ -2,5 +2,5 @@ package com.ffii.tsms.modules.project.entity;

import com.ffii.core.support.AbstractRepository

interface PaymentMilestoneRepository : AbstractRepository<PaymentMilestone, Long> {
interface MilestoneRepository : AbstractRepository<Milestone, Long> {
}

+ 8
- 0
src/main/java/com/ffii/tsms/modules/project/entity/Project.kt Переглянути файл

@@ -18,6 +18,14 @@ open class Project : BaseEntity<Long>() {
@Column(name = "description")
open var description: String? = null

@NotNull
@Column(name = "code", length = 30)
open var code: String? = null

@ManyToOne
@JoinColumn(name = "projectCategoryId")
open var projectCategory: ProjectCategory? = null

@Column(name = "planStart")
open var planStart: LocalDate? = null



+ 15
- 0
src/main/java/com/ffii/tsms/modules/project/entity/ProjectCategory.kt Переглянути файл

@@ -0,0 +1,15 @@
package com.ffii.tsms.modules.project.entity
import com.ffii.core.entity.IdEntity
import jakarta.persistence.Column
import jakarta.persistence.Entity
import jakarta.persistence.Table
import jakarta.validation.constraints.NotNull
@Entity
@Table(name = "project_category")
open class ProjectCategory : IdEntity<Long>() {
@NotNull
@Column(name = "name")
open var name: String? = null
}

+ 6
- 0
src/main/java/com/ffii/tsms/modules/project/entity/ProjectCategoryRepository.kt Переглянути файл

@@ -0,0 +1,6 @@
package com.ffii.tsms.modules.project.entity;
import com.ffii.core.support.AbstractRepository
interface ProjectCategoryRepository : AbstractRepository<ProjectCategory, Long> {
}

+ 1
- 1
src/main/java/com/ffii/tsms/modules/project/entity/ProjectTask.kt Переглянути файл

@@ -13,7 +13,7 @@ open class ProjectTask : IdEntity<Long>() {

@ManyToOne
@JoinColumn(name = "milestoneId")
open var paymentMilestone: PaymentMilestone? = null
open var milestone: Milestone? = null

@NotNull
@ManyToOne


+ 43
- 0
src/main/java/com/ffii/tsms/modules/project/service/ProjectsService.kt Переглянути файл

@@ -0,0 +1,43 @@
package com.ffii.tsms.modules.project.service

import com.ffii.tsms.modules.data.entity.StaffRepository
import com.ffii.tsms.modules.data.service.CustomerService
import com.ffii.tsms.modules.project.entity.Project
import com.ffii.tsms.modules.project.entity.ProjectCategory
import com.ffii.tsms.modules.project.entity.ProjectCategoryRepository
import com.ffii.tsms.modules.project.entity.ProjectRepository
import com.ffii.tsms.modules.project.web.models.NewProjectRequest
import org.springframework.stereotype.Service

@Service
class ProjectsService(
private val projectRepository: ProjectRepository,
private val customerService: CustomerService, private val projectCategoryRepository: ProjectCategoryRepository,
private val staffRepository: StaffRepository
) {
fun allProjects(): List<Project> {
return projectRepository.findAll()
}

fun allProjectCategories(): List<ProjectCategory> {
return projectCategoryRepository.findAll()
}

fun saveProject(request: NewProjectRequest): Project {
val projectCategory = projectCategoryRepository.findById(request.projectCategoryId).orElseThrow()
val teamLead = staffRepository.findById(request.projectLeadId).orElseThrow()
val customer = customerService.saveCustomer(request.clientName, request.clientCode, request.clientEmail, request.clientPhone, request.clientContactName)

// TODO: Add tasks, milestones, allocated
val project = Project().apply {
name = request.projectName
description = request.projectDescription
code = request.projectCode
this.projectCategory = projectCategory
this.teamLead = teamLead
this.customer = customer
}

return projectRepository.save(project)
}
}

+ 18
- 5
src/main/java/com/ffii/tsms/modules/project/web/ProjectsController.kt Переглянути файл

@@ -1,14 +1,27 @@
package com.ffii.tsms.modules.project.web

import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
import com.ffii.tsms.modules.project.entity.Project
import com.ffii.tsms.modules.project.entity.ProjectCategory
import com.ffii.tsms.modules.project.service.ProjectsService
import com.ffii.tsms.modules.project.web.models.NewProjectRequest
import jakarta.validation.Valid
import org.springframework.web.bind.annotation.*

@RestController
@RequestMapping("/projects")
class ProjectsController {
class ProjectsController(private val projectsService: ProjectsService) {
@GetMapping
fun allProjects() {
fun allProjects(): List<Project> {
return projectsService.allProjects()
}

@GetMapping("/categories")
fun projectCategories(): List<ProjectCategory> {
return projectsService.allProjectCategories()
}

@PostMapping("/new")
fun saveProject(@Valid @RequestBody newProject: NewProjectRequest): Project {
return projectsService.saveProject(newProject)
}
}

+ 44
- 0
src/main/java/com/ffii/tsms/modules/project/web/models/NewProjectRequest.kt Переглянути файл

@@ -0,0 +1,44 @@
package com.ffii.tsms.modules.project.web.models

import jakarta.validation.constraints.NotBlank

data class NewProjectRequest(
@field:NotBlank(message = "project code cannot be empty")
val projectCode: String,
@field:NotBlank(message = "project name cannot be empty")
val projectName: String,

val projectCategoryId: Long,
val projectDescription: String,
val projectLeadId: Long,

val clientCode: String,
val clientName: String,
val clientContactName: String,
val clientPhone: String,
val clientEmail: String,
val clientSubsidiary: String,

val tasks: Map<Long, TaskAllocation>,

val allocatedStaffIds: List<Long>,

val milestones: Map<Long, Milestone>
)

data class TaskAllocation(
val manhourAllocation: Map<Long, Double>
)

data class Milestone(
val startDate: String?,
val endDate: String?,
val payments: List<PaymentInputs>
)

data class PaymentInputs(
val id: Long,
val description: String,
val date: String,
val amount: Double
)

+ 41
- 0
src/main/resources/db/changelog/changes/20240318_01_wayne/01_salary_data.sql Переглянути файл

@@ -0,0 +1,41 @@
-- liquibase formatted sql
-- changeset wayne:salary_data
INSERT INTO salary (salaryPoint, lowerLimit, upperLimit, increment) VALUES
(36, 170001, 180000, 10000),
(35, 160001, 170000, 10000),
(34, 150001, 160000, 10000),
(33, 140001, 150000, 10000),
(32, 130001, 140000, 10000),
(31, 120001, 130000, 10000),
(30, 110001, 120000, 10000),
(29, 100001, 110000, 10000),
(28, 90001, 100000, 10000),
(27, 80001, 90000, 10000),
(26, 70001, 80000, 10000),
(25, 68001, 70000, 2000),
(24, 66001, 68000, 2000),
(23, 64001, 66000, 2000),
(22, 62001, 64000, 2000),
(21, 60001, 62000, 2000),
(20, 58001, 60000, 2000),
(19, 56001, 58000, 2000),
(18, 54001, 56000, 2000),
(17, 52001, 54000, 2000),
(16, 50001, 52000, 2000),
(15, 47001, 50000, 3000),
(14, 44001, 47000, 3000),
(13, 41001, 44000, 3000),
(12, 38001, 41000, 3000),
(11, 35001, 38000, 3000),
(10, 33001, 35000, 2000),
(9, 31001, 33000, 2000),
(8, 29001, 31000, 2000),
(7, 27001, 29000, 2000),
(6, 25001, 27000, 2000),
(5, 23001, 25000, 2000),
(4, 21001, 23000, 2000),
(3, 19001, 21000, 2000),
(2, 17001, 19000, 2000),
(1, 15001, 17000, 2000);

+ 35
- 0
src/main/resources/db/changelog/changes/20240318_01_wayne/02_mock_team_leads.sql Переглянути файл

@@ -0,0 +1,35 @@
-- liquibase formatted sql
-- changeset wayne:mock_team_leads
INSERT INTO `user` (name, username, password) VALUES
('Wayne Lee','wlee','$2a$10$65S7/AhKn8MldlYmvFN5JOfr1yaULwFNDIhTskLTuUCKgbbs8sFAi'),
('Ming Chan','mchan','$2a$10$65S7/AhKn8MldlYmvFN5JOfr1yaULwFNDIhTskLTuUCKgbbs8sFAi');
INSERT INTO company (companyCode, name) VALUES
('ABC', 'Company ABC');
INSERT INTO team (name, code) VALUES
('Team Wayne Lee', 'WL'),
('Team Ming Chan', 'MC');
INSERT INTO salary_effective (date, salaryId) VALUES
(current_date, 1);
INSERT INTO staff (userId, name, staffId, companyId, teamId, salaryEffId) VALUES
(
(SELECT id from `user` where username = 'wlee'),
'Wayne Lee',
'001',
(SELECT id from company where companyCode = 'ABC'),
(SELECT id from team where code = 'WL'),
(SELECT id from salary_effective where salaryId = 1)
),
(
(SELECT id from `user` where username = 'mchan'),
'Ming Chan',
'002',
(SELECT id from company where companyCode = 'ABC'),
(SELECT id from team where code = 'MC'),
(SELECT id from salary_effective where salaryId = 1)
);

+ 12
- 0
src/main/resources/db/changelog/changes/20240318_01_wayne/03_project_categories.sql Переглянути файл

@@ -0,0 +1,12 @@
-- liquibase formatted sql
-- changeset wayne:project_category
CREATE TABLE project_category (
id INT NOT NULL AUTO_INCREMENT,
name VARCHAR(255) NOT NULL,
CONSTRAINT pk_project_category PRIMARY KEY (id)
);
INSERT INTO project_category (name) VALUES
('Project to be bidded'),
('Confirmed Project');

+ 7
- 0
src/main/resources/db/changelog/changes/20240318_01_wayne/04_update_project.sql Переглянути файл

@@ -0,0 +1,7 @@
-- liquibase formatted sql
-- changeset wayne:update_project
ALTER TABLE project ADD code VARCHAR(30) NOT NULL;
ALTER TABLE project ADD projectCategoryId INT NULL;
ALTER TABLE project ADD CONSTRAINT FK_PROJECT_ON_PROJECTCATEGORYID FOREIGN KEY (projectCategoryId) REFERENCES project_category (id);

Завантаження…
Відмінити
Зберегти