Просмотр исходного кода

Add project creation

tags/Baseline_30082024_BACKEND_UAT
Wayne 1 год назад
Родитель
Сommit
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);

Загрузка…
Отмена
Сохранить