Przeglądaj źródła

update project, subsidiary

tags/Baseline_30082024_BACKEND_UAT
cyril.tsui 1 rok temu
rodzic
commit
6ea265f255
12 zmienionych plików z 197 dodań i 69 usunięć
  1. +16
    -0
      src/main/java/com/ffii/tsms/modules/data/entity/Subsidiary.java
  2. +5
    -6
      src/main/java/com/ffii/tsms/modules/data/entity/SubsidiaryContact.java
  3. +2
    -0
      src/main/java/com/ffii/tsms/modules/data/entity/SubsidiaryRepository.java
  4. +10
    -0
      src/main/java/com/ffii/tsms/modules/project/entity/Project.kt
  5. +3
    -0
      src/main/java/com/ffii/tsms/modules/project/entity/ProjectRepository.kt
  6. +1
    -0
      src/main/java/com/ffii/tsms/modules/project/entity/projections/ProjectSearchInfo.kt
  7. +128
    -61
      src/main/java/com/ffii/tsms/modules/project/service/ProjectsService.kt
  8. +3
    -0
      src/main/java/com/ffii/tsms/modules/project/web/models/EditProjectDetails.kt
  9. +6
    -2
      src/main/java/com/ffii/tsms/modules/project/web/models/NewProjectRequest.kt
  10. +13
    -0
      src/main/resources/db/changelog/changes/20240513_01_cyril/01_update_project.sql
  11. +5
    -0
      src/main/resources/db/changelog/changes/20240513_01_cyril/02_update_project.sql
  12. +5
    -0
      src/main/resources/db/changelog/changes/20240514_01_cyril/01_update_project.sql

+ 16
- 0
src/main/java/com/ffii/tsms/modules/data/entity/Subsidiary.java Wyświetl plik

@@ -1,10 +1,14 @@
package com.ffii.tsms.modules.data.entity;

import com.fasterxml.jackson.annotation.JsonManagedReference;
import com.ffii.core.entity.BaseEntity;
import jakarta.persistence.*;
import jakarta.validation.constraints.NotNull;

import java.time.LocalTime;
import java.util.List;

import static jakarta.persistence.CascadeType.ALL;

@Entity
@Table(name = "subsidiary")
@@ -31,6 +35,10 @@ public class Subsidiary extends BaseEntity<Long> {
@JoinColumn(name = "typeId")
private SubsidiaryType subsidiaryType;

@OneToMany(mappedBy = "subsidiary", cascade = ALL, orphanRemoval = true)
@JsonManagedReference
private List<SubsidiaryContact> subsidiaryContacts;

public String getAddress() {
return address;
}
@@ -78,4 +86,12 @@ public class Subsidiary extends BaseEntity<Long> {
public void setSubsidiaryType(SubsidiaryType subsidiaryType) {
this.subsidiaryType = subsidiaryType;
}

public List<SubsidiaryContact> getSubsidiaryContacts() {
return subsidiaryContacts;
}

public void setSubsidiaryContacts(List<SubsidiaryContact> subsidiaryContacts) {
this.subsidiaryContacts = subsidiaryContacts;
}
}

+ 5
- 6
src/main/java/com/ffii/tsms/modules/data/entity/SubsidiaryContact.java Wyświetl plik

@@ -1,18 +1,17 @@
package com.ffii.tsms.modules.data.entity;

import com.fasterxml.jackson.annotation.JsonBackReference;
import com.fasterxml.jackson.annotation.JsonManagedReference;
import com.ffii.core.entity.IdEntity;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.OneToOne;
import jakarta.persistence.Table;
import jakarta.persistence.*;
import jakarta.validation.constraints.NotNull;

@Entity
@Table(name = "subsidiary_contact")
public class SubsidiaryContact extends IdEntity<Long> {
@NotNull
@OneToOne
@ManyToOne
@JsonBackReference
@JoinColumn(name = "subsidiaryId")
private Subsidiary subsidiary;



+ 2
- 0
src/main/java/com/ffii/tsms/modules/data/entity/SubsidiaryRepository.java Wyświetl plik

@@ -9,5 +9,7 @@ import java.util.Optional;
public interface SubsidiaryRepository extends AbstractRepository<Subsidiary, Long> {
List<Subsidiary> findAllByDeletedFalse();

List<Subsidiary> findAllByDeletedFalseAndIdIn(List<Long> id);

Optional<Subsidiary> findByCode(@Param("code") String code);
}

+ 10
- 0
src/main/java/com/ffii/tsms/modules/project/entity/Project.kt Wyświetl plik

@@ -108,4 +108,14 @@ open class Project : BaseEntity<Long>() {
inverseJoinColumns = [JoinColumn(name = "workNaturesId")]
)
open var workNatures: MutableSet<WorkNature> = mutableSetOf()

@ManyToOne
@JoinColumn(name = "taskTemplateId")
open var taskTemplate: TaskTemplate? = null

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

@Column(name = "isClpProject")
open var isClpProject: Boolean? = null
}

+ 3
- 0
src/main/java/com/ffii/tsms/modules/project/entity/ProjectRepository.kt Wyświetl plik

@@ -4,6 +4,7 @@ import com.ffii.core.support.AbstractRepository
import com.ffii.tsms.modules.project.entity.projections.InvoiceInfoSearchInfo
import com.ffii.tsms.modules.project.entity.projections.InvoiceSearchInfo
import com.ffii.tsms.modules.project.entity.projections.ProjectSearchInfo
import java.io.Serializable

interface ProjectRepository : AbstractRepository<Project, Long> {
fun findProjectSearchInfoByOrderByCreatedDesc(): List<ProjectSearchInfo>
@@ -13,4 +14,6 @@ interface ProjectRepository : AbstractRepository<Project, Long> {
fun findInvoiceSearchInfoById(id: Long): List<InvoiceSearchInfo>

fun findInvoiceInfoSearchInfoById(id: Long): List<InvoiceInfoSearchInfo>

fun findFirstByIsClpProjectAndIdNotOrderByIdDesc(isClpProject: Boolean, id: Serializable?): Project?
}

+ 1
- 0
src/main/java/com/ffii/tsms/modules/project/entity/projections/ProjectSearchInfo.kt Wyświetl plik

@@ -9,6 +9,7 @@ interface ProjectSearchInfo {
val id: Long?
val name: String?
val code: String?
val status: String?

@get:Value("#{target.projectCategory.name}")
val category: String?


+ 128
- 61
src/main/java/com/ffii/tsms/modules/project/service/ProjectsService.kt Wyświetl plik

@@ -40,8 +40,11 @@ open class ProjectsService(
private val milestoneRepository: MilestoneRepository,
private val gradeAllocationRepository: GradeAllocationRepository,
private val projectTaskRepository: ProjectTaskRepository,
private val milestonePaymentRepository: MilestonePaymentRepository, private val taskGroupRepository: TaskGroupRepository,
private val timesheetRepository: TimesheetRepository
private val milestonePaymentRepository: MilestonePaymentRepository,
private val taskGroupRepository: TaskGroupRepository,
private val timesheetRepository: TimesheetRepository,
private val taskTemplateRepository: TaskTemplateRepository,
private val subsidiaryRepository: SubsidiaryRepository, private val subsidiaryContactRepository: SubsidiaryContactRepository
) {
open fun allProjects(): List<ProjectSearchInfo> {
return projectRepository.findProjectSearchInfoByOrderByCreatedDesc()
@@ -60,34 +63,42 @@ open class ProjectsService(
}

open fun markDeleted(id: Long) {
projectRepository.save(projectRepository.findById(id).orElseThrow().apply { deleted = true })
projectRepository.save(projectRepository.findById(id).orElseThrow()
.apply {
deleted = true
status = "Deleted"
})
}

open fun allAssignedProjects(): List<AssignedProject> {
return SecurityUtils.getUser().getOrNull()?.let { user ->
staffRepository.findByUserId(user.id).getOrNull()?.let { staff ->
staffAllocationRepository.findAssignedProjectsByStaff(staff)
.mapNotNull { it.project?.let { project ->
val timesheetHours = timesheetRepository.totalHoursConsumedByProject(project)

AssignedProject(
id = project.id!!,
code = project.code!!,
name = project.name!!,
tasks = projectTaskRepository.findAllByProject(project).mapNotNull { pt -> pt.task },
milestones = milestoneRepository.findAllByProject(project)
.filter { milestone -> milestone.taskGroup?.id != null }
.associateBy { milestone -> milestone.taskGroup!!.id!! }
.mapValues { (_, milestone) -> MilestoneInfo(
startDate = milestone.startDate?.format(DateTimeFormatter.ISO_LOCAL_DATE),
endDate = milestone.endDate?.format(DateTimeFormatter.ISO_LOCAL_DATE)
) },
hoursAllocated = project.totalManhour ?: 0.0,
hoursAllocatedOther = 0.0,
hoursSpent = timesheetHours.normalConsumed,
hoursSpentOther = timesheetHours.otConsumed
)
} }
.mapNotNull {
it.project?.let { project ->
val timesheetHours = timesheetRepository.totalHoursConsumedByProject(project)

AssignedProject(
id = project.id!!,
code = project.code!!,
name = project.name!!,
tasks = projectTaskRepository.findAllByProject(project).mapNotNull { pt -> pt.task },
milestones = milestoneRepository.findAllByProject(project)
.filter { milestone -> milestone.taskGroup?.id != null }
.associateBy { milestone -> milestone.taskGroup!!.id!! }
.mapValues { (_, milestone) ->
MilestoneInfo(
startDate = milestone.startDate?.format(DateTimeFormatter.ISO_LOCAL_DATE),
endDate = milestone.endDate?.format(DateTimeFormatter.ISO_LOCAL_DATE)
)
},
hoursAllocated = project.totalManhour ?: 0.0,
hoursAllocatedOther = 0.0,
hoursSpent = timesheetHours.normalConsumed,
hoursSpentOther = timesheetHours.otConsumed
)
}
}
}
} ?: emptyList()
}
@@ -102,10 +113,12 @@ open class ProjectsService(
milestones = milestoneRepository.findAllByProject(project)
.filter { milestone -> milestone.taskGroup?.id != null }
.associateBy { milestone -> milestone.taskGroup!!.id!! }
.mapValues { (_, milestone) -> MilestoneInfo(
startDate = milestone.startDate?.format(DateTimeFormatter.ISO_LOCAL_DATE),
endDate = milestone.endDate?.format(DateTimeFormatter.ISO_LOCAL_DATE)
) }
.mapValues { (_, milestone) ->
MilestoneInfo(
startDate = milestone.startDate?.format(DateTimeFormatter.ISO_LOCAL_DATE),
endDate = milestone.endDate?.format(DateTimeFormatter.ISO_LOCAL_DATE)
)
}
)
}
}
@@ -114,6 +127,19 @@ open class ProjectsService(
return projectCategoryRepository.findAll()
}

open fun createProjectCode(isClpProject: Boolean?, project: Project): String {
val checkIsClpProject = isClpProject != null && isClpProject
val prefix = if (checkIsClpProject) "C" else "M"

val latestProjectCode = projectRepository.findFirstByIsClpProjectAndIdNotOrderByIdDesc(checkIsClpProject, project.id)

if (latestProjectCode != null) {
val lastFix = latestProjectCode.code!!.split("-")[1] //C-0001 -> 0001
return "$prefix-" + String.format("%04d", lastFix.toLong() + 1L)
} else {
return "$prefix-0001"
}
}
@Transactional
open fun saveProject(request: NewProjectRequest): NewProjectResponse {
val projectCategory =
@@ -124,9 +150,12 @@ open class ProjectsService(
val location = locationRepository.findById(request.locationId).orElseThrow()
val buildingTypes = buildingTypeRepository.findAllById(request.buildingTypeIds).toMutableSet()
val workNatures = workNatureRepository.findAllById(request.workNatureIds).toMutableSet()

val taskTemplate =
if (request.taskTemplateId != null && request.taskTemplateId > 0) taskTemplateRepository.findById(request.taskTemplateId)
.orElseThrow() else null
val teamLead = staffRepository.findById(request.projectLeadId).orElseThrow()
val customer = customerService.findCustomer(request.clientId)
val subsidiaryContact = subsidiaryContactRepository.findById(request.clientContactId).orElse(null)
val clientContact = customerContactService.findByContactId(request.clientContactId)
val customerSubsidiary = request.clientSubsidiaryId?.let { subsidiaryService.findSubsidiary(it) }

@@ -134,15 +163,24 @@ open class ProjectsService(
val taskGroupMap = tasksService.allTaskGroups().associateBy { it.id }
val gradeMap = gradeService.allGrades().associateBy { it.id }

val project = if (request.projectId != null && request.projectId > 0) projectRepository.findById(request.projectId).orElseThrow() else Project()
val project =
if (request.projectId != null && request.projectId > 0) projectRepository.findById(request.projectId)
.orElseThrow() else Project()
project.apply {
name = request.projectName
description = request.projectDescription
code = request.projectCode
println(this.code)
println(this.code.isNullOrEmpty())
code = if (this.code.isNullOrEmpty()) createProjectCode(request.isClpProject, project) else this.code
expectedTotalFee = request.expectedProjectFee
totalManhour = request.totalManhour
actualStart = request.projectActualStart
actualEnd = request.projectActualEnd
status = if (this.status == "Deleted" || this.deleted == true) "Deleted"
else if (this.actualStart != null && this.actualEnd != null) "Completed"
else if (this.actualStart != null) "On-going"
else "Pending To Start"
isClpProject = request.isClpProject

this.projectCategory = projectCategory
this.fundingType = fundingType
@@ -151,12 +189,13 @@ open class ProjectsService(
this.location = location
this.buildingTypes = buildingTypes
this.workNatures = workNatures
this.taskTemplate = taskTemplate

this.teamLead = teamLead
this.customer = customer
custLeadName = clientContact.name
custLeadEmail = clientContact.email
custLeadPhone = clientContact.phone
custLeadName = if (request.isSubsidiaryContact == null || !request.isSubsidiaryContact) clientContact.name else subsidiaryContact.name
custLeadEmail = if (request.isSubsidiaryContact == null || !request.isSubsidiaryContact) clientContact.email else subsidiaryContact.email
custLeadPhone = if (request.isSubsidiaryContact == null || !request.isSubsidiaryContact) clientContact.phone else subsidiaryContact.phone
this.customerSubsidiary = customerSubsidiary
}

@@ -165,7 +204,10 @@ open class ProjectsService(
val tasksToSave = mutableListOf<ProjectTask>()
val milestones = request.taskGroups.entries.map { (taskStageId, taskGroupAllocation) ->
val taskGroup = taskGroupRepository.findById(taskStageId).orElse(TaskGroup()) ?: TaskGroup()
val milestone = if (project.id != null && project.id!! > 0L) milestoneRepository.findByProjectAndTaskGroup(project, taskGroup) ?: Milestone() else Milestone()
val milestone = if (project.id != null && project.id!! > 0L) milestoneRepository.findByProjectAndTaskGroup(
project,
taskGroup
) ?: Milestone() else Milestone()
milestone.apply {
val newMilestone = this
val requestMilestone = request.milestones[taskStageId]
@@ -177,7 +219,8 @@ open class ProjectsService(
this.milestonePayments.removeAll(this.milestonePayments)
}
requestMilestone?.payments?.map {
val milestonePayment = milestonePaymentRepository.findById(it.id).orElse(MilestonePayment()) ?:MilestonePayment()
val milestonePayment =
milestonePaymentRepository.findById(it.id).orElse(MilestonePayment()) ?: MilestonePayment()
this.milestonePayments.add(milestonePayment.apply {
this.milestone = newMilestone
this.description = it.description
@@ -190,7 +233,11 @@ open class ProjectsService(
this.stagePercentAllocation = taskGroupAllocation.percentAllocation

taskGroupAllocation.taskIds.map { taskId ->
val projectTask = if (project.id != null && project.id!! > 0L) projectTaskRepository.findByProjectAndTask(project, allTasksMap[taskId]!!) ?:ProjectTask() else ProjectTask()
val projectTask =
if (project.id != null && project.id!! > 0L) projectTaskRepository.findByProjectAndTask(
project,
allTasksMap[taskId]!!
) ?: ProjectTask() else ProjectTask()

projectTask.apply {
this.project = project
@@ -205,7 +252,11 @@ open class ProjectsService(

// Grade allocation (from manhourPercentageByGrade)
val gradeAllocations = request.manhourPercentageByGrade.entries.map {
val gradeAllocation = if (project.id != null && project.id!! > 0L) gradeAllocationRepository.findByProjectAndGrade(project, gradeMap[it.key]!!) ?: GradeAllocation() else GradeAllocation()
val gradeAllocation =
if (project.id != null && project.id!! > 0L) gradeAllocationRepository.findByProjectAndGrade(
project,
gradeMap[it.key]!!
) ?: GradeAllocation() else GradeAllocation()

gradeAllocation.apply {
this.project = project
@@ -225,7 +276,8 @@ open class ProjectsService(

val milestonesToDelete = milestoneRepository.findAllByProject(project).subtract(milestones.toSet())
val tasksToDelete = projectTaskRepository.findAllByProject(project).subtract(tasksToSave.toSet())
val gradeAllocationsToDelete = gradeAllocationRepository.findByProject(project).subtract(gradeAllocations.toSet())
val gradeAllocationsToDelete =
gradeAllocationRepository.findByProject(project).subtract(gradeAllocations.toSet())
milestoneRepository.deleteAll(milestonesToDelete)
projectTaskRepository.deleteAll(tasksToDelete)
gradeAllocationRepository.deleteAll(gradeAllocationsToDelete)
@@ -236,11 +288,14 @@ open class ProjectsService(

// Staff allocation
val allocatedStaff = staffRepository.findAllById(request.allocatedStaffIds)
val staffAllocations = allocatedStaff.map { staff -> StaffAllocation().apply {
this.project = savedProject
this.staff = staff
} }
val staffAllocationsToDelete = staffAllocationRepository.findByProject(savedProject).subtract(staffAllocations.toSet())
val staffAllocations = allocatedStaff.map { staff ->
StaffAllocation().apply {
this.project = savedProject
this.staff = staff
}
}
val staffAllocationsToDelete =
staffAllocationRepository.findByProject(savedProject).subtract(staffAllocations.toSet())
staffAllocationRepository.deleteAll(staffAllocationsToDelete)
staffAllocationRepository.saveAll(staffAllocations)

@@ -260,7 +315,9 @@ open class ProjectsService(
val project = projectRepository.findById(projectId)

return project.getOrNull()?.let {
val customerContact = it.customer?.id?.let { customerId -> customerContactService.findAllByCustomerId(customerId) } ?: emptyList()
val customerContact =
it.customer?.id?.let { customerId -> customerContactService.findAllByCustomerId(customerId) }
?: emptyList()

val milestoneMap = it.milestones
.filter { milestone -> milestone.taskGroup?.id != null }
@@ -276,11 +333,14 @@ open class ProjectsService(
projectLeadId = it.teamLead?.id,
projectActualStart = it.actualStart,
projectActualEnd = it.actualEnd,
projectStatus = it.status,
isClpProject = it.isClpProject,
serviceTypeId = it.serviceType?.id,
fundingTypeId = it.fundingType?.id,
contractTypeId = it.contractType?.id,
locationId = it.location?.id,
buildingTypeIds = it.buildingTypes.mapNotNull { buildingType -> buildingType.id },
taskTemplateId = it.taskTemplate?.id,
buildingTypeIds = it.buildingTypes.mapNotNull { buildingType -> buildingType.id },
workNatureIds = it.workNatures.mapNotNull { workNature -> workNature.id },
clientId = it.customer?.id,
clientContactId = customerContact.find { contact -> contact.name == it.custLeadName }?.id,
@@ -292,21 +352,28 @@ open class ProjectsService(
taskGroups = projectTaskRepository.findAllByProject(it)
.mapNotNull { projectTask -> if (projectTask.task?.taskGroup?.id != null) projectTask.task else null }
.groupBy { task -> task.taskGroup!!.id!! }
.mapValues { (taskGroupId, tasks) -> TaskGroupAllocation(
taskIds = tasks.mapNotNull { task -> task.id },
percentAllocation = milestoneMap[taskGroupId]?.stagePercentAllocation ?: 0.0
) },
allocatedStaffIds = staffAllocationRepository.findByProject(it).mapNotNull { allocation -> allocation.staff?.id },
milestones = milestoneMap.mapValues { (_, milestone) -> com.ffii.tsms.modules.project.web.models.Milestone(
startDate = milestone.startDate?.format(DateTimeFormatter.ISO_LOCAL_DATE),
endDate = milestone.endDate?.format(DateTimeFormatter.ISO_LOCAL_DATE),
payments = milestone.milestonePayments.map { payment -> PaymentInputs(
id = payment.id!!,
amount = payment.amount!!,
description = payment.description!!,
date = payment.date!!.format(DateTimeFormatter.ISO_LOCAL_DATE)
)}
)},
.mapValues { (taskGroupId, tasks) ->
TaskGroupAllocation(
taskIds = tasks.mapNotNull { task -> task.id },
percentAllocation = milestoneMap[taskGroupId]?.stagePercentAllocation ?: 0.0
)
},
allocatedStaffIds = staffAllocationRepository.findByProject(it)
.mapNotNull { allocation -> allocation.staff?.id },
milestones = milestoneMap.mapValues { (_, milestone) ->
com.ffii.tsms.modules.project.web.models.Milestone(
startDate = milestone.startDate?.format(DateTimeFormatter.ISO_LOCAL_DATE),
endDate = milestone.endDate?.format(DateTimeFormatter.ISO_LOCAL_DATE),
payments = milestone.milestonePayments.map { payment ->
PaymentInputs(
id = payment.id!!,
amount = payment.amount!!,
description = payment.description!!,
date = payment.date!!.format(DateTimeFormatter.ISO_LOCAL_DATE)
)
}
)
},
expectedProjectFee = it.expectedTotalFee
)
}


+ 3
- 0
src/main/java/com/ffii/tsms/modules/project/web/models/EditProjectDetails.kt Wyświetl plik

@@ -13,6 +13,8 @@ data class EditProjectDetails(
val projectLeadId: Long?,
val projectActualStart: LocalDate?,
val projectActualEnd: LocalDate?,
val projectStatus: String?,
val isClpProject: Boolean?,

val serviceTypeId: Long?,
val fundingTypeId: Long?,
@@ -20,6 +22,7 @@ data class EditProjectDetails(
val locationId: Long?,
val buildingTypeIds: List<Long>,
val workNatureIds: List<Long>,
val taskTemplateId: Long?,

// Client details
val clientId: Long?,


+ 6
- 2
src/main/java/com/ffii/tsms/modules/project/web/models/NewProjectRequest.kt Wyświetl plik

@@ -1,12 +1,13 @@
package com.ffii.tsms.modules.project.web.models

import com.ffii.tsms.modules.data.entity.SubsidiaryContact
import jakarta.validation.constraints.NotBlank
import java.time.LocalDate

data class NewProjectRequest(
// Project details
@field:NotBlank(message = "project code cannot be empty")
val projectCode: String,
// @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,
@@ -15,6 +16,7 @@ data class NewProjectRequest(
val projectId: Long?,
val projectActualStart: LocalDate?,
val projectActualEnd: LocalDate?,
val isClpProject: Boolean?,

val serviceTypeId: Long,
val fundingTypeId: Long,
@@ -22,6 +24,8 @@ data class NewProjectRequest(
val locationId: Long,
val buildingTypeIds: List<Long>,
val workNatureIds: List<Long>,
val taskTemplateId: Long?,
val isSubsidiaryContact: Boolean?,

// Client details
val clientId: Long,


+ 13
- 0
src/main/resources/db/changelog/changes/20240513_01_cyril/01_update_project.sql Wyświetl plik

@@ -0,0 +1,13 @@
-- liquibase formatted sql
-- changeset cyril:project

ALTER TABLE `project`
ADD COLUMN `taskTemplateId` INT NULL DEFAULT NULL AFTER `customerSubsidiaryId`,
ADD INDEX `FK_PROJECT_ON_TASKTEMPLATEID` (`taskTemplateId` ASC) VISIBLE;
;
ALTER TABLE `project`
ADD CONSTRAINT `FK_PROJECT_ON_TASKTEMPLATEID`
FOREIGN KEY (`taskTemplateId`)
REFERENCES `task_template` (`id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION;

+ 5
- 0
src/main/resources/db/changelog/changes/20240513_01_cyril/02_update_project.sql Wyświetl plik

@@ -0,0 +1,5 @@
-- liquibase formatted sql
-- changeset cyril:project

ALTER TABLE `project`
ADD COLUMN `status` VARCHAR(40) NULL DEFAULT 'Pending to Start' AFTER `taskTemplateId`;

+ 5
- 0
src/main/resources/db/changelog/changes/20240514_01_cyril/01_update_project.sql Wyświetl plik

@@ -0,0 +1,5 @@
-- liquibase formatted sql
-- changeset cyril:project

ALTER TABLE `project`
ADD COLUMN `isClpProject` TINYINT NULL DEFAULT 0 AFTER `status`;

Ładowanie…
Anuluj
Zapisz