@@ -35,11 +35,16 @@ dependencies { | |||
implementation group: 'jakarta.validation', name: 'jakarta.validation-api', version: '3.0.2' | |||
implementation group: 'com.fasterxml.jackson.dataformat', name: 'jackson-dataformat-yaml', version: '2.15.2' | |||
implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.15.2' | |||
implementation group: 'com.fasterxml.jackson.module', name: 'jackson-module-kotlin', version: '2.15.2' | |||
implementation group: 'io.jsonwebtoken', name: 'jjwt-api', version: '0.11.5' | |||
implementation group: 'io.jsonwebtoken', name: 'jjwt-impl', version: '0.11.5' | |||
implementation group: 'io.jsonwebtoken', name: 'jjwt-jackson', version: '0.11.5' | |||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8" | |||
implementation "org.jetbrains.kotlin:kotlin-reflect" | |||
compileOnly group: 'jakarta.servlet', name: 'jakarta.servlet-api', version: '6.0.0' | |||
runtimeOnly 'com.mysql:mysql-connector-j' | |||
@@ -47,7 +52,6 @@ dependencies { | |||
testImplementation 'org.springframework.boot:spring-boot-starter-test' | |||
testImplementation 'org.springframework.security:spring-security-test' | |||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8" | |||
} | |||
configurations { | |||
@@ -1,20 +1,24 @@ | |||
package com.ffii.tsms.modules.project.entity | |||
import com.ffii.core.entity.BaseEntity | |||
import jakarta.persistence.Column | |||
import jakarta.persistence.Entity | |||
import jakarta.persistence.Table | |||
import jakarta.persistence.* | |||
import jakarta.validation.constraints.NotNull | |||
import org.hibernate.proxy.HibernateProxy | |||
@Entity | |||
@Table(name = "task") | |||
open class Task : BaseEntity<Long>() { | |||
@NotNull | |||
@Column(name = "name") | |||
open var name: String? = null | |||
@Column(name = "description") | |||
open var description: String? = null | |||
@ManyToOne | |||
@JoinColumn(name = "taskGroupId") | |||
open var taskGroup: TaskGroup? = null | |||
final override fun equals(other: Any?): Boolean { | |||
if (this === other) return true | |||
if (other == null) return false | |||
@@ -0,0 +1,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.Table | |||
@Entity | |||
@Table(name = "task_group") | |||
open class TaskGroup : IdEntity<Long>() { | |||
@Column(name = "name") | |||
open var name: String? = null | |||
} |
@@ -19,5 +19,6 @@ open class TaskTemplate : IdEntity<Long>() { | |||
@JoinTable(name = "task_template_tasks", | |||
joinColumns = [JoinColumn(name = "taskTemplateId")], | |||
inverseJoinColumns = [JoinColumn(name = "tasksId")]) | |||
open var tasks: MutableSet<Task> = mutableSetOf() | |||
@OrderBy | |||
open var tasks: MutableList<Task> = mutableListOf() | |||
} |
@@ -0,0 +1,31 @@ | |||
package com.ffii.tsms.modules.project.service | |||
import com.ffii.tsms.modules.project.entity.Task | |||
import com.ffii.tsms.modules.project.entity.TaskRepository | |||
import com.ffii.tsms.modules.project.entity.TaskTemplate | |||
import com.ffii.tsms.modules.project.entity.TaskTemplateRepository | |||
import org.springframework.stereotype.Service | |||
@Service | |||
class TasksService( | |||
private val taskTemplateRepository: TaskTemplateRepository, | |||
private val taskRepository: TaskRepository | |||
) { | |||
fun allTasks(): List<Task> { | |||
return taskRepository.findAll() | |||
} | |||
fun allTaskTemplates(): List<TaskTemplate> { | |||
return taskTemplateRepository.findAll() | |||
} | |||
fun saveTaskTemplate(code: String, name: String, taskIds: List<Long>): TaskTemplate { | |||
return taskTemplateRepository.save<TaskTemplate>( | |||
TaskTemplate().apply { | |||
this.name = name | |||
this.code = code | |||
this.tasks = taskRepository.findAllById(taskIds) | |||
} | |||
) | |||
} | |||
} |
@@ -0,0 +1,14 @@ | |||
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 | |||
@RestController | |||
@RequestMapping("/projects") | |||
class ProjectsController { | |||
@GetMapping | |||
fun allProjects() { | |||
} | |||
} |
@@ -0,0 +1,35 @@ | |||
package com.ffii.tsms.modules.project.web | |||
import com.ffii.tsms.modules.project.entity.Task | |||
import com.ffii.tsms.modules.project.entity.TaskTemplate | |||
import com.ffii.tsms.modules.project.service.TasksService | |||
import com.ffii.tsms.modules.project.web.models.NewTaskTemplateRequest | |||
import jakarta.validation.Valid | |||
import org.springframework.web.bind.annotation.GetMapping | |||
import org.springframework.web.bind.annotation.PostMapping | |||
import org.springframework.web.bind.annotation.RequestBody | |||
import org.springframework.web.bind.annotation.RequestMapping | |||
import org.springframework.web.bind.annotation.RestController | |||
@RestController | |||
@RequestMapping("/tasks") | |||
class TasksController(private val tasksService: TasksService) { | |||
@GetMapping | |||
fun allTasks(): List<Task> { | |||
return tasksService.allTasks() | |||
} | |||
@GetMapping("/templates") | |||
fun allTaskTemplates(): List<TaskTemplate> { | |||
return tasksService.allTaskTemplates() | |||
} | |||
@PostMapping("/templates/new") | |||
fun saveTaskTemplate(@Valid @RequestBody newTaskTemplate: NewTaskTemplateRequest): TaskTemplate { | |||
return tasksService.saveTaskTemplate( | |||
newTaskTemplate.code, | |||
newTaskTemplate.name, | |||
newTaskTemplate.taskIds | |||
) | |||
} | |||
} |
@@ -0,0 +1,11 @@ | |||
package com.ffii.tsms.modules.project.web.models | |||
import jakarta.validation.constraints.NotBlank | |||
data class NewTaskTemplateRequest( | |||
@field:NotBlank(message = "code cannot be empty") | |||
val code: String, | |||
@field:NotBlank(message = "name cannot be empty") | |||
val name: String, | |||
val taskIds: List<Long> = emptyList() | |||
) |
@@ -1,6 +1,12 @@ | |||
-- liquibase formatted sql | |||
-- changeset wayne:task | |||
CREATE TABLE task_group ( | |||
id INT NOT NULL AUTO_INCREMENT, | |||
name VARCHAR(255) NULL, | |||
CONSTRAINT pk_task_group PRIMARY KEY (id) | |||
); | |||
CREATE TABLE task ( | |||
id INT NOT NULL AUTO_INCREMENT, | |||
version INT NOT NULL DEFAULT '0', | |||
@@ -9,11 +15,14 @@ CREATE TABLE task ( | |||
modified datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, | |||
modifiedBy VARCHAR(30) NULL, | |||
deleted TINYINT(1) NOT NULL DEFAULT '0', | |||
name VARCHAR(255) NULL, | |||
name VARCHAR(255) NOT NULL, | |||
`description` VARCHAR(255) NULL, | |||
taskGroupId INT NULL, | |||
CONSTRAINT pk_task PRIMARY KEY (id) | |||
); | |||
ALTER TABLE task ADD CONSTRAINT FK_TASK_ON_TASKGROUPID FOREIGN KEY (taskGroupId) REFERENCES task_group (id); | |||
CREATE TABLE task_template ( | |||
id INT NOT NULL AUTO_INCREMENT, | |||
code VARCHAR(255) NOT NULL, | |||
@@ -0,0 +1,63 @@ | |||
-- liquibase formatted sql | |||
-- changeset wayne:task_data | |||
INSERT | |||
INTO | |||
task_group | |||
(name) | |||
VALUES | |||
('1. Design & Cost Planning / Estimating'), | |||
('2. Tender Documentation'), | |||
('3. Tender Analysis & Report & Contract Documentation'), | |||
('4. Construction / Post Construction'), | |||
('5. Miscellaneous'); | |||
INSERT | |||
INTO | |||
task | |||
(name, taskGroupId) | |||
VALUES | |||
('1.1 Preparation of preliminary Cost Estimate / Cost Plan including Revised & Refined', 1), | |||
('1.2 Cash flow forecast', 1), | |||
('1.3 Cost studies for alternative design solutions', 1), | |||
('1.4 Attend design co-ordination / project review meetings', 1), | |||
('1.5 Prepare / Review RIC', 1), | |||
('2.1 Advise on tendering & contractual arrangement', 2), | |||
('2.2 Drafting / Vetting front-parts (incl. Main Contract, Sub-contracts & Direct Contracts)', 2), | |||
('2.3 Carry out pre-qualification exercise / EOI', 2), | |||
('2.4 Measurement (incl. billing of items) for Works Packages', 2), | |||
('2.5 Measurement (incl. billing of items) for tender addendum for Works Packages', 2), | |||
('2.6 Bulk Checking of Bills of Quantities', 2), | |||
('2.7 Line through drawings & specifications to check against Bills of Quantities / SOR', 2), | |||
('2.8 Update cash flow forecast', 2), | |||
('2.9 Edit tender documents (Incl. Bills of Quantities / SOR)', 2), | |||
('2.10 Preparation of pre-tender estimates', 2), | |||
('2.11 Attend design co-ordination / project review meetings / project meetings', 2), | |||
('3.1 Evaluation of tenders (incl. arithmetical checking, submission checking, etc)', 3), | |||
('3.2 Preparation of 3-rates bills', 3), | |||
('3.3 Preparation of Report on Tenderers (incl. three-rates bills)', 3), | |||
('3.4 Preparation of tender queries', 3), | |||
('3.5 Attend tender interviews', 3), | |||
('3.6 Draft Letter of Acceptance / Award', 3), | |||
('3.7 Preparation of Contract Documents for Works Packages', 3), | |||
('4.1 Check insurance policies, surety bond, guarantee, etc.', 4), | |||
('4.2 Valuation of works completed for progress payment (incl. site visits)', 4), | |||
('4.3 Preparation of financial statements (incl. cash flow forecasts)', 4), | |||
('4.4 Cost check / advice on a alternative design solutions', 4), | |||
('4.5 Cost estimate for draft AIs/EIs/SIs', 4), | |||
('4.6 Advise on contractual issues & evaluate monetary contractual claim', 4), | |||
('4.7 Attend site meetings / project co-ordination meetings / project meetings', 4), | |||
('4.8 Measurement & valuation of variations / prime cost & provisional sums', 4), | |||
('4.9 Negotiation and settlement of final accounts (incl. meetings)', 4), | |||
('4.10 Preparation of Statement of Final Account', 4), | |||
('4.11 Preparation of Cost Analysis for the Completed project', 4), | |||
('4.12 Check / Review draft final bills', 4), | |||
('4.13 Carry out site check for draft final bills', 4), | |||
('5.1 Preparation of Fee Proposal / Expression of Interest', 5), | |||
('5.2 Attend Management Meeting / Management Workshop', 5), | |||
('5.3 Preparation of project budget i.e. manhours vs fee receivables', 5), | |||
('5.4 Attend Local / International Conference / Seminar / Webinar', 5); |
@@ -0,0 +1,57 @@ | |||
-- liquibase formatted sql | |||
-- changeset wayne:mock_task_templates | |||
INSERT INTO task_template (code,name) VALUES | |||
('Pre-001','Pre-contract Template'), | |||
('Post-001','Post-contract Template'), | |||
('Full-001','Full Project Template'); | |||
INSERT INTO task_template_tasks (taskTemplateId,tasksId) VALUES | |||
(1,1), | |||
(2,1), | |||
(3,1), | |||
(1,2), | |||
(3,2), | |||
(1,3), | |||
(2,3), | |||
(3,3), | |||
(3,4), | |||
(3,5), | |||
(1,6), | |||
(3,6), | |||
(1,7), | |||
(3,7), | |||
(3,8), | |||
(3,9), | |||
(3,10), | |||
(3,11), | |||
(3,12), | |||
(3,13), | |||
(3,14), | |||
(3,15), | |||
(3,16), | |||
(3,17), | |||
(3,18), | |||
(3,19), | |||
(3,20), | |||
(3,21), | |||
(3,22), | |||
(3,23), | |||
(3,24), | |||
(3,25), | |||
(3,26), | |||
(3,27), | |||
(3,28), | |||
(3,29), | |||
(3,30), | |||
(3,31), | |||
(3,32), | |||
(3,33), | |||
(3,34), | |||
(3,35), | |||
(3,36), | |||
(3,37), | |||
(3,38), | |||
(3,39), | |||
(3,40); |