# Conflicts: # src/main/java/com/ffii/tsms/modules/report/service/ReportService.kt # src/main/resources/templates/report/AR01_Late Start Report v01.xlsxtags/Baseline_30082024_BACKEND_UAT
@@ -509,8 +509,8 @@ open class DashboardService( | |||
+ " p.name as projectName," | |||
+ " t.code as team," | |||
+ " s.name as teamLead," | |||
+ " p.actualStart as startDate," | |||
+ " p.planEnd as targetEndDate," | |||
+ " date_format(p.actualStart, '%Y-%m-%d') as startDate," | |||
+ " date_format(p.planEnd, '%Y-%m-%d') as targetEndDate," | |||
+ " c.name as client," | |||
+ " coalesce(s2.name,'N/A') as subsidiary" | |||
+ " from project p" | |||
@@ -524,6 +524,390 @@ open class DashboardService( | |||
return jdbcDao.queryForList(sql.toString(), args) | |||
} | |||
fun CashFlowMonthlyIncomeByMonth(args: Map<String, Any>): List<Map<String, Any>> { | |||
val sql = StringBuilder("select" | |||
+ " months.month as monthInvoice," | |||
+ " coalesce (invoice.invoiceMonth,'-') as invoiceMonth," | |||
+ " coalesce (invoice.income,0) as income," | |||
+ " SUM(COALESCE(invoice.income, 0)) OVER (ORDER BY months.month) AS cumulativeIncome" | |||
+ " FROM (" | |||
+ " SELECT 01 AS month" | |||
+ " UNION" | |||
+ " SELECT 02" | |||
+ " UNION" | |||
+ " SELECT 03" | |||
+ " UNION" | |||
+ " SELECT 04" | |||
+ " UNION" | |||
+ " SELECT 05" | |||
+ " UNION" | |||
+ " SELECT 06" | |||
+ " UNION" | |||
+ " SELECT 07" | |||
+ " UNION" | |||
+ " SELECT 08" | |||
+ " UNION" | |||
+ " SELECT 09" | |||
+ " UNION" | |||
+ " SELECT 10" | |||
+ " UNION" | |||
+ " SELECT 11" | |||
+ " union" | |||
+ " select 12" | |||
+ " ) AS months" | |||
+ " left join(" | |||
+ " select" | |||
+ " month(i.receiptDate) as invoiceMonth," | |||
+ " coalesce(sum(i.paidAmount),0) as income" | |||
+ " from project p" | |||
+ " left join invoice i on p.code = i.projectCode" | |||
+ " where p.status = 'On-going'" | |||
+ " and p.id in (:projectIds)" | |||
+ " and year(i.receiptDate) = :year" | |||
+ " and i.id is not null" | |||
+ " group by month(i.receiptDate)" | |||
+ " ) as invoice on months.month = invoice.invoiceMonth" | |||
) | |||
return jdbcDao.queryForList(sql.toString(), args) | |||
} | |||
fun CashFlowMonthlyExpenditureByMonth(args: Map<String, Any>): List<Map<String, Any>> { | |||
val sql = StringBuilder("select" | |||
+ " months.month as monthExpenditure," | |||
+ " coalesce (expenditure.recordMonth,'-') as recordMonth," | |||
+ " coalesce (expenditure.expenditure,0) as expenditure," | |||
+ " SUM(COALESCE(expenditure.expenditure, 0)) OVER (ORDER BY months.month) AS cumulativeExpenditure" | |||
+ " FROM (" | |||
+ " SELECT 01 AS month" | |||
+ " UNION" | |||
+ " SELECT 02" | |||
+ " UNION" | |||
+ " SELECT 03" | |||
+ " UNION" | |||
+ " SELECT 04" | |||
+ " UNION" | |||
+ " SELECT 05" | |||
+ " UNION" | |||
+ " SELECT 06" | |||
+ " UNION" | |||
+ " SELECT 07" | |||
+ " UNION" | |||
+ " SELECT 08" | |||
+ " UNION" | |||
+ " SELECT 09" | |||
+ " UNION" | |||
+ " SELECT 10" | |||
+ " UNION" | |||
+ " SELECT 11" | |||
+ " union" | |||
+ " select 12" | |||
+ " ) AS months" | |||
+ " left join(" | |||
+ " SELECT" | |||
+ " r.recordMonth as recordMonth," | |||
+ " sum(r.cumulativeExpenditure) as expenditure" | |||
+ " from(" | |||
+ " select" | |||
+ " month(t.recordDate) as recordMonth," | |||
+ " (coalesce(sum(t.normalConsumed),0) * s2.hourlyRate) + (coalesce(sum(t.otConsumed),0) * s2.hourlyRate * 1.0) as cumulativeExpenditure" | |||
+ " from project p" | |||
+ " left join project_task pt on p.id = pt.project_id" | |||
+ " left join timesheet t on pt.id = t.projectTaskId" | |||
+ " left join staff s on t.staffId = s.id" | |||
+ " left join salary s2 on s.salaryId = s2.salaryPoint" | |||
+ " where t.id is not null" | |||
+ " and p.id in (:projectIds)" | |||
+ " and year(t.recordDate) = :year" | |||
+ " group by month(t.recordDate),s2.hourlyRate" | |||
+ " ) as r" | |||
+ " group by r.recordMonth" | |||
+ " ) as expenditure on months.month = expenditure.recordMonth" | |||
) | |||
return jdbcDao.queryForList(sql.toString(), args) | |||
} | |||
fun CashFlowReceivableAndExpenditure(args: Map<String, Any>): List<Map<String, Any>> { | |||
val sql = StringBuilder("select" | |||
+ " coalesce (round(sum(i.paidAmount)/sum(i.issueAmount)*100,0),0) as receivedPercentage," | |||
+ " coalesce (round(expenditure.expenditure/(sum(p.expectedTotalFee)*0.8)*100,0),0) as expenditurePercentage," | |||
+ " coalesce (sum(i.issueAmount),0) as totalInvoiced," | |||
+ " coalesce (sum(i.paidAmount),0) as totalReceived," | |||
+ " coalesce (sum(i.issueAmount) - sum(i.paidAmount),0) as receivable," | |||
+ " coalesce (round(sum(p.expectedTotalFee)*0.8,2),0) as totalBudget," | |||
+ " coalesce (expenditure.expenditure) as totalExpenditure," | |||
+ " coalesce (sum(p.expectedTotalFee)*0.8 - expenditure.expenditure,0) as expenditureReceivable" | |||
+ " from project p" | |||
+ " left join invoice i on p.code = i.projectCode" | |||
+ " left join(" | |||
+ " select" | |||
+ " sum(r.expenditure) as expenditure" | |||
+ " from(" | |||
+ " select" | |||
+ " (coalesce(sum(t.normalConsumed),0) * s2.hourlyRate) + (coalesce(sum(t.otConsumed),0) * s2.hourlyRate * 1.0) as expenditure" | |||
+ " from project p" | |||
+ " left join project_task pt on p.id = pt.project_id" | |||
+ " left join timesheet t on pt.id = t.projectTaskId" | |||
+ " left join staff s on t.staffId = s.id" | |||
+ " left join salary s2 on s.salaryId = s2.salaryPoint" | |||
+ " where t.id is not null" | |||
+ " and p.id in (:projectIds)" | |||
+ " group by s2.hourlyRate" | |||
+ " ) as r" | |||
+ " ) as expenditure on 1=1" | |||
+ " where p.id in (:projectIds)" | |||
+ " group by expenditure.expenditure" | |||
) | |||
return jdbcDao.queryForList(sql.toString(), args) | |||
} | |||
fun CashFlowAnticipateIncome(args: Map<String, Any>): List<Map<String, Any>> { | |||
val sql = StringBuilder("select" | |||
+ " months.month as monthanticipateIncome," | |||
+ " coalesce (anticipateIncome.anticipateIncomeDate,'-') as anticipateIncomeDate," | |||
+ " coalesce (anticipateIncome.anticipateIncome,0) as anticipateIncome" | |||
+ " FROM (" | |||
+ " SELECT 01 AS month" | |||
+ " UNION" | |||
+ " SELECT 02" | |||
+ " UNION" | |||
+ " SELECT 03" | |||
+ " UNION" | |||
+ " SELECT 04" | |||
+ " UNION" | |||
+ " SELECT 05" | |||
+ " UNION" | |||
+ " SELECT 06" | |||
+ " UNION" | |||
+ " SELECT 07" | |||
+ " UNION" | |||
+ " SELECT 08" | |||
+ " UNION" | |||
+ " SELECT 09" | |||
+ " UNION" | |||
+ " SELECT 10" | |||
+ " UNION" | |||
+ " SELECT 11" | |||
+ " union" | |||
+ " select 12" | |||
+ " ) AS months" | |||
+ " left join(" | |||
+ " select" | |||
+ " month(mp.date) as anticipateIncomeDate," | |||
+ " sum(mp.amount) as anticipateIncome" | |||
+ " from project p" | |||
+ " left join milestone m on p.id = m.projectId" | |||
+ " left join milestone_payment mp on m.id = mp.milestoneId" | |||
+ " where p.id in (:projectIds)" | |||
+ " and year(mp.date) = :year" | |||
+ " group by month(mp.date)" | |||
+ " ) as anticipateIncome on months.month = anticipateIncome.anticipateIncomeDate" | |||
) | |||
return jdbcDao.queryForList(sql.toString(), args) | |||
} | |||
fun CashFlowAnticipateExpenditure(args: Map<String, Any>): List<Map<String, Any>> { | |||
val sql = StringBuilder("select" | |||
+ " p.id, p.name," | |||
+ " date_format(p.planStart, '%Y-%m') as planStart," | |||
+ " date_format(p.planEnd, '%Y-%m') as planEnd," | |||
+ " case" | |||
+ " when year(p.planStart) < :year then 1" | |||
+ " when year(p.planStart) = :year then month(p.planStart)" | |||
+ " end as startMonth," | |||
+ " case" | |||
+ " when year(p.planStart) < :year and year(p.planEnd) > :year then 12" | |||
+ " when year(p.planStart) < :year and year(p.planEnd) = :year then month(p.planEnd)" | |||
+ " when year(p.planStart) = :year and year(p.planEnd) > :year then 12 - month(p.planStart)" | |||
+ " else PERIOD_DIFF(DATE_FORMAT(p.planEnd, '%Y%m'), DATE_FORMAT(p.planStart, '%Y%m'))+1" | |||
+ " end AS 'Duration'," | |||
+ " PERIOD_DIFF(DATE_FORMAT(p.planEnd, '%Y%m'), DATE_FORMAT(p.planStart, '%Y%m'))+1 as projectDuration," | |||
+ " p.expectedTotalFee*0.8 as totalBudget," | |||
+ " (p.expectedTotalFee*0.8) / (PERIOD_DIFF(DATE_FORMAT(p.planEnd, '%Y%m'), DATE_FORMAT(p.planStart, '%Y%m'))+1) as aniticipateExpenditure," | |||
+ " ROUND(p.totalManhour / (PERIOD_DIFF(DATE_FORMAT(p.planEnd, '%Y%m'), DATE_FORMAT(p.planStart, '%Y%m'))+1), 2) AS 'AverageManhours'," | |||
+ " p.teamLead, p.totalManhour" | |||
+ " FROM project p" | |||
+ " WHERE p.status = 'On-going'" | |||
+ " and p.id in (:projectIds)" | |||
+ " and (year(p.planStart) <= :year and year(p.planEnd) >= :year)" | |||
+ " order by teamLead, planStart" | |||
) | |||
return jdbcDao.queryForList(sql.toString(), args) | |||
} | |||
fun CashFlowLedger(args: Map<String, Any>): List<Map<String, Any>> { | |||
val sql = StringBuilder("select" | |||
+ " ROW_NUMBER() OVER (ORDER BY date, income, expenditure) AS id," | |||
+ " date," | |||
+ " COALESCE(ROUND(income, 2), 0) AS income," | |||
+ " COALESCE(ROUND(expenditure, 2), 0) AS expenditure," | |||
+ " ROUND(SUM(COALESCE(income, 0) - COALESCE(expenditure, 0)) OVER (ORDER BY date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), 2) AS balance," | |||
+ " CASE" | |||
+ " WHEN income > 0 THEN paymentMilestone" | |||
+ " ELSE 'Monthly Manpower Expenditure'" | |||
+ " END AS remarks" | |||
+ " FROM" | |||
+ " (" | |||
+ " SELECT" | |||
+ " date_format(i.receiptDate, '%b %y') AS date," | |||
+ " sum(i.paidAmount) AS income," | |||
+ " NULL AS expenditure," | |||
+ " i.paymentMilestone AS paymentMilestone" | |||
+ " FROM" | |||
+ " project p" | |||
+ " LEFT JOIN invoice i ON p.code = i.projectCode" | |||
+ " WHERE" | |||
+ " p.id IN (:projectIds)" | |||
+ " AND i.paidAmount IS NOT NULL" | |||
+ " GROUP BY" | |||
+ " date_format(i.receiptDate, '%b %y')," | |||
+ " i.paymentMilestone" | |||
+ " UNION" | |||
+ " SELECT" | |||
+ " date_format(r.date, '%b %y') AS date," | |||
+ " NULL AS income," | |||
+ " sum(r.expenditure) AS expenditure," | |||
+ " NULL AS paymentMilestone" | |||
+ " FROM" | |||
+ " (" | |||
+ " SELECT" | |||
+ " t.recordDate AS date," | |||
+ " (COALESCE(SUM(t.normalConsumed), 0) * s2.hourlyRate) + (COALESCE(SUM(t.otConsumed), 0) * s2.hourlyRate * 1.0) AS expenditure" | |||
+ " FROM" | |||
+ " project p" | |||
+ " LEFT JOIN project_task pt ON p.id = pt.project_id" | |||
+ " LEFT JOIN timesheet t ON pt.id = t.projectTaskId" | |||
+ " LEFT JOIN staff s ON t.staffId = s.id" | |||
+ " LEFT JOIN salary s2 ON s.salaryId = s2.salaryPoint" | |||
+ " WHERE" | |||
+ " t.id IS NOT NULL" | |||
+ " AND p.id IN (:projectIds)" | |||
+ " GROUP BY" | |||
+ " s2.hourlyRate," | |||
+ " t.recordDate" | |||
+ " ) AS r" | |||
+ " GROUP BY" | |||
+ " date_format(r.date, '%b %y')" | |||
+ " ) AS combined_data" | |||
+ " ORDER BY" | |||
+ " date" | |||
) | |||
return jdbcDao.queryForList(sql.toString(), args) | |||
} | |||
fun TeamCashFlowIncome(args: Map<String, Any>): List<Map<String, Any>> { | |||
val sql = StringBuilder("select" | |||
+ " months.month as monthInvoice," | |||
+ " coalesce (invoice.invoiceMonth,'-') as invoiceMonth," | |||
+ " coalesce (invoice.income,0) as income," | |||
+ " SUM(COALESCE(invoice.income, 0)) OVER (ORDER BY months.month) AS cumulativeIncome" | |||
+ " FROM (" | |||
+ " SELECT 01 AS month" | |||
+ " UNION" | |||
+ " SELECT 02" | |||
+ " UNION" | |||
+ " SELECT 03" | |||
+ " UNION" | |||
+ " SELECT 04" | |||
+ " UNION" | |||
+ " SELECT 05" | |||
+ " UNION" | |||
+ " SELECT 06" | |||
+ " UNION" | |||
+ " SELECT 07" | |||
+ " UNION" | |||
+ " SELECT 08" | |||
+ " UNION" | |||
+ " SELECT 09" | |||
+ " UNION" | |||
+ " SELECT 10" | |||
+ " UNION" | |||
+ " SELECT 11" | |||
+ " union" | |||
+ " select 12" | |||
+ " ) AS months" | |||
+ " left join(" | |||
+ " select" | |||
+ " month(i.receiptDate) as invoiceMonth," | |||
+ " coalesce(sum(i.paidAmount),0) as income" | |||
+ " from project p" | |||
+ " left join team t on p.teamLead = t.teamLead" | |||
+ " left join invoice i on p.code = i.projectCode" | |||
+ " where p.status = 'On-going'" | |||
) | |||
if (args != null) { | |||
if (args.containsKey("teamId")) | |||
sql.append(" AND t.id = :teamId") | |||
} | |||
sql.append(" and year(i.receiptDate) = :year" | |||
+ " and i.id is not null" | |||
+ " group by month(i.receiptDate)" | |||
+ " ) as invoice on months.month = invoice.invoiceMonth") | |||
return jdbcDao.queryForList(sql.toString(), args) | |||
} | |||
fun TeamCashFlowExpenditure(args: Map<String, Any>): List<Map<String, Any>> { | |||
val sql = StringBuilder("select" | |||
+ " months.month as monthExpenditure," | |||
+ " coalesce (expenditure.recordMonth,'-') as recordMonth," | |||
+ " coalesce (expenditure.expenditure,0) as expenditure," | |||
+ " SUM(COALESCE(expenditure.expenditure, 0)) OVER (ORDER BY months.month) AS cumulativeExpenditure" | |||
+ " FROM (" | |||
+ " SELECT 01 AS month" | |||
+ " UNION" | |||
+ " SELECT 02" | |||
+ " UNION" | |||
+ " SELECT 03" | |||
+ " UNION" | |||
+ " SELECT 04" | |||
+ " UNION" | |||
+ " SELECT 05" | |||
+ " UNION" | |||
+ " SELECT 06" | |||
+ " UNION" | |||
+ " SELECT 07" | |||
+ " UNION" | |||
+ " SELECT 08" | |||
+ " UNION" | |||
+ " SELECT 09" | |||
+ " UNION" | |||
+ " SELECT 10" | |||
+ " UNION" | |||
+ " SELECT 11" | |||
+ " union" | |||
+ " select 12" | |||
+ " ) AS months" | |||
+ " left join(" | |||
+ " SELECT" | |||
+ " r.recordMonth as recordMonth," | |||
+ " sum(r.cumulativeExpenditure) as expenditure" | |||
+ " from(" | |||
+ " select" | |||
+ " month(t.recordDate) as recordMonth," | |||
+ " (coalesce(sum(t.normalConsumed),0) * s2.hourlyRate) + (coalesce(sum(t.otConsumed),0) * s2.hourlyRate * 1.0) as cumulativeExpenditure" | |||
+ " from project p" | |||
+ " left join team t2 on p.teamLead = t2.teamLead" | |||
+ " left join project_task pt on p.id = pt.project_id" | |||
+ " left join timesheet t on pt.id = t.projectTaskId" | |||
+ " left join staff s on t.staffId = s.id" | |||
+ " left join salary s2 on s.salaryId = s2.salaryPoint" | |||
+ " where t.id is not null" | |||
) | |||
if (args != null) { | |||
if (args.containsKey("teamId")) | |||
sql.append(" AND t2.id = :teamId") | |||
} | |||
sql.append(" and year(t.recordDate) = :year" | |||
+ " group by month(t.recordDate),s2.hourlyRate" | |||
+ " ) as r" | |||
+ " group by r.recordMonth" | |||
+ " ) as expenditure on months.month = expenditure.recordMonth") | |||
return jdbcDao.queryForList(sql.toString(), args) | |||
} | |||
} | |||
@@ -41,15 +41,15 @@ open class TeamService( | |||
val ids = req.addStaffIds!! | |||
// println(ids) | |||
val teamLead = staffRepository.findById(ids[0]).orElseThrow() | |||
val teamName = "Team " + teamLead.name | |||
val initials = teamLead.name.split(" ").map { it.first() } | |||
val teamCode = initials.joinToString("") | |||
// val teamName = "Team " + teamLead.name | |||
// | |||
// val initials = teamLead.name.split(" ").map { it.first() } | |||
// val teamCode = initials.joinToString("") | |||
val team = Team().apply { | |||
this.staff = teamLead | |||
name = teamName | |||
code = teamCode | |||
name = req.name | |||
code = req.code | |||
description = req.description | |||
} | |||
teamRepository.saveAndFlush(team) | |||
@@ -68,26 +68,23 @@ open class TeamService( | |||
val addIds = req.addStaffIds ?: listOf<Int>() | |||
val teamLead: Staff | |||
val teamName: String | |||
val teamCode: String | |||
// val teamName: String | |||
// val teamCode: String | |||
if (addIds.isNotEmpty()) { | |||
val leader = staffRepository.findById(addIds[0].toLong()).orElseThrow() | |||
teamName = "Team " + leader.name | |||
// teamName = "Team " + leader.name | |||
teamLead = leader; | |||
val initials = leader.name.split(" ").map { it.first() } | |||
teamCode = initials.joinToString("") | |||
// val initials = leader.name.split(" ").map { it.first() } | |||
// teamCode = initials.joinToString("") | |||
} else { | |||
teamLead = team.staff | |||
teamName = team.name | |||
teamCode = team.code | |||
} | |||
team.apply { | |||
this.staff = teamLead | |||
name = teamName | |||
code = teamCode | |||
name = req.name | |||
code = req.code | |||
description = req.description | |||
} | |||
@@ -131,4 +131,80 @@ class DashboardController( | |||
val args = mutableMapOf<String, Any>() | |||
return dashboardService.CashFlowProject(args) | |||
} | |||
@GetMapping("/searchCashFlowByMonth") | |||
fun searchCashFlowByMonth(request: HttpServletRequest?): List<Map<String, Any>> { | |||
val args = mutableMapOf<String, Any>() | |||
val projectIdList = request?.getParameter("projectIdList") | |||
val year = request?.getParameter("year") | |||
val projectIds = projectIdList?.split(",")?.map { it.toInt() }?.toList() | |||
if (projectIds != null) { | |||
args["projectIds"] = projectIds | |||
} | |||
if (year != null) { | |||
args["year"] = year | |||
} | |||
val result = mutableMapOf<String, Any>() | |||
val cashFlowMonthlyIncome = dashboardService.CashFlowMonthlyIncomeByMonth(args) | |||
val cashFlowMonthlyExpenditure = dashboardService.CashFlowMonthlyExpenditureByMonth(args) | |||
result["incomeList"] = cashFlowMonthlyIncome | |||
result["expenditureList"] = cashFlowMonthlyExpenditure | |||
return listOf(result) | |||
} | |||
@GetMapping("/searchCashFlowReceivableAndExpenditure") | |||
fun searchCashFlowReceivableAndExpenditure(request: HttpServletRequest?): List<Map<String, Any>> { | |||
val args = mutableMapOf<String, Any>() | |||
val projectIdList = request?.getParameter("projectIdList") | |||
val projectIds = projectIdList?.split(",")?.map { it.toInt() }?.toList() | |||
if (projectIds != null) { | |||
args["projectIds"] = projectIds | |||
} | |||
return dashboardService.CashFlowReceivableAndExpenditure(args) | |||
} | |||
@GetMapping("/searchCashFlowAnticipate") | |||
fun searchCashFlowAnticipate(request: HttpServletRequest?): List<Map<String, Any>> { | |||
val args = mutableMapOf<String, Any>() | |||
val projectIdList = request?.getParameter("projectIdList") | |||
val year = request?.getParameter("year") | |||
val projectIds = projectIdList?.split(",")?.map { it.toInt() }?.toList() | |||
if (projectIds != null) { | |||
args["projectIds"] = projectIds | |||
} | |||
if (year != null) { | |||
args["year"] = year | |||
} | |||
val result = mutableMapOf<String, Any>() | |||
val cashFlowAnticipateIncome = dashboardService.CashFlowAnticipateIncome(args) | |||
val cashFlowAnticipateExpenditure = dashboardService.CashFlowAnticipateExpenditure(args) | |||
result["anticipateIncomeList"] = cashFlowAnticipateIncome | |||
result["anticipateExpenditureList"] = cashFlowAnticipateExpenditure | |||
return listOf(result) | |||
} | |||
@GetMapping("/searchCashFlowLedger") | |||
fun searchCashFlowLedger(request: HttpServletRequest?): List<Map<String, Any>> { | |||
val args = mutableMapOf<String, Any>() | |||
val projectIdList = request?.getParameter("projectIdList") | |||
val projectIds = projectIdList?.split(",")?.map { it.toInt() }?.toList() | |||
if (projectIds != null) { | |||
args["projectIds"] = projectIds | |||
} | |||
return dashboardService.CashFlowLedger(args) | |||
} | |||
@GetMapping("/searchTeamCashFlow") | |||
fun searchTeamCashFlow(request: HttpServletRequest?): List<Map<String, Any>> { | |||
val args = mutableMapOf<String, Any>() | |||
val teamId = request?.getParameter("teamId") | |||
val year = request?.getParameter("year") | |||
if (teamId != null) { | |||
args["teamId"] = teamId | |||
} | |||
if (year != null) { | |||
args["year"] = year | |||
} | |||
val result = mutableMapOf<String, Any>() | |||
val teamCashFlowIncome = dashboardService.TeamCashFlowIncome(args) | |||
val teamCashFlowExpenditure = dashboardService.TeamCashFlowExpenditure(args) | |||
result["teamCashFlowIncome"] = teamCashFlowIncome | |||
result["teamCashFlowExpenditure"] = teamCashFlowExpenditure | |||
return listOf(result) | |||
} | |||
} |
@@ -1,8 +1,11 @@ | |||
package com.ffii.tsms.modules.data.web | |||
import com.ffii.core.exception.NotFoundException | |||
import com.ffii.core.response.RecordsRes | |||
import com.ffii.core.utils.CriteriaArgsBuilder | |||
import com.ffii.core.utils.Params | |||
import com.ffii.tsms.modules.data.entity.Team | |||
import com.ffii.tsms.modules.data.service.StaffsService | |||
import com.ffii.tsms.modules.data.service.TeamService | |||
import com.ffii.tsms.modules.data.web.models.NewTeamRequest | |||
import jakarta.servlet.http.HttpServletRequest | |||
@@ -15,7 +18,10 @@ import org.springframework.web.bind.annotation.* | |||
@RestController | |||
@RequestMapping("/team") | |||
class TeamController(private val teamService: TeamService) { | |||
class TeamController( | |||
private val teamService: TeamService, | |||
private val staffsService: StaffsService, | |||
) { | |||
@GetMapping | |||
fun allStaff(args: Map<String, Any>): List<Map<String, Any>> { | |||
@@ -34,6 +40,21 @@ class TeamController(private val teamService: TeamService) { | |||
return teamService.getTeamDetail(args); | |||
} | |||
@GetMapping("/{id}") | |||
fun getStaff(@PathVariable id: Long): Map<String, Any> { | |||
val staffList = staffsService.findAllByTeamId(id).orElseThrow { NotFoundException() } | |||
val staffIdList: MutableList<Long> = mutableListOf() | |||
for (staff in staffList) { | |||
staffIdList.add(staff.id as Long) | |||
} | |||
// val map: Map<String, Any> = java.util.Map.of("team" to teamService.find(id).orElseThrow { NotFoundException() }) | |||
// map["staffIds"] = staffIdList | |||
return java.util.Map.of( | |||
"team", staffsService.find(id).orElseThrow { NotFoundException() }, | |||
"staffIds", staffIdList | |||
) | |||
} | |||
// @Transactional(rollbackFor = [Exception::class]) | |||
@DeleteMapping("/delete/{id}") | |||
@ResponseStatus(HttpStatus.NO_CONTENT) | |||
@@ -13,21 +13,21 @@ data class NewStaffRequest( | |||
val companyId: Long, | |||
@field:NotNull(message = "Staff salaryId cannot be empty") | |||
val salaryId: Long, | |||
@field:NotNull(message = "joinDate cannot be empty") | |||
// @field:NotNull(message = "joinDate cannot be empty") | |||
val joinDate: LocalDate, | |||
@field:NotNull(message = "Staff currentPositionId cannot be empty") | |||
val currentPositionId: Long, | |||
@field:NotNull(message = "Staff joinPositionId cannot be empty") | |||
// @field:NotNull(message = "Staff joinPositionId cannot be empty") | |||
val joinPositionId: Long, | |||
@field:NotNull(message = "Staff departmentId cannot be empty") | |||
// @field:NotNull(message = "Staff departmentId cannot be empty") | |||
val departmentId: Long, | |||
@field:NotBlank(message = "Staff phone1 cannot be empty") | |||
val phone1: String, | |||
@field:NotBlank(message = "Staff email cannot be empty") | |||
val email: String, | |||
@field:NotBlank(message = "Staff emergContactName cannot be empty") | |||
// @field:NotBlank(message = "Staff emergContactName cannot be empty") | |||
val emergContactName: String, | |||
@field:NotBlank(message = "Staff emergContactPhone cannot be empty") | |||
// @field:NotBlank(message = "Staff emergContactPhone cannot be empty") | |||
val emergContactPhone: String, | |||
@field:NotBlank(message = "Staff employType cannot be empty") | |||
val employType: String, | |||
@@ -6,7 +6,8 @@ import java.time.LocalDate | |||
data class NewTeamRequest ( | |||
val addStaffIds: List<Long>?, | |||
val name: String, | |||
val code: String, | |||
val deleteStaffIds: List<Long>?, | |||
val description: String?, | |||
val id: Long? |
@@ -1,10 +1,13 @@ | |||
package com.ffii.tsms.modules.project.entity; | |||
import com.ffii.core.support.AbstractRepository | |||
import com.ffii.tsms.modules.data.entity.Customer | |||
import com.ffii.tsms.modules.data.entity.Staff | |||
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 org.springframework.data.jpa.repository.Query | |||
import org.springframework.lang.Nullable | |||
import java.io.Serializable | |||
import java.time.LocalDate | |||
@@ -25,8 +28,10 @@ interface ProjectRepository : AbstractRepository<Project, Long> { | |||
"") | |||
fun getLatestCodeNumberByMainProject(isClpProject: Boolean, id: Serializable?): Long? | |||
@Query("SELECT max(case when length(p.code) - length(replace(p.code, '-', '')) > 1 then cast(substring_index(p.code, '-', -1) as long) end) FROM Project p WHERE p.code like ?1 and p.id != ?2") | |||
@Query("SELECT max(case when length(p.code) - length(replace(p.code, '-', '')) > 1 then cast(substring_index(p.code, '-', -1) as long) end) FROM Project p WHERE p.code like %?1% and p.id != ?2") | |||
fun getLatestCodeNumberBySubProject(code: String, id: Serializable?): Long? | |||
fun findAllByStatusIsNotAndMainProjectIsNull(status: String): List<Project> | |||
fun findAllByTeamLeadAndCustomer(teamLead: Staff, customer: Customer): List<Project> | |||
} |
@@ -5,5 +5,6 @@ import com.ffii.core.support.AbstractRepository | |||
interface ProjectTaskRepository : AbstractRepository<ProjectTask, Long> { | |||
fun findAllByProject(project: Project): List<ProjectTask> | |||
fun findAllByProjectIn(projects: List<Project>): List<ProjectTask> | |||
fun findByProjectAndTask(project: Project, task: Task): ProjectTask? | |||
} |
@@ -2,11 +2,9 @@ package com.ffii.tsms.modules.report.web | |||
import com.fasterxml.jackson.databind.ObjectMapper | |||
import com.fasterxml.jackson.module.kotlin.KotlinModule | |||
import com.ffii.tsms.modules.data.entity.Customer | |||
import com.ffii.tsms.modules.data.entity.StaffRepository | |||
import com.ffii.tsms.modules.data.entity.* | |||
//import com.ffii.tsms.modules.data.entity.projections.FinancialStatusReportInfo | |||
import com.ffii.tsms.modules.data.entity.projections.StaffSearchInfo | |||
import com.ffii.tsms.modules.data.entity.Team | |||
import com.ffii.tsms.modules.data.service.CustomerService | |||
import com.ffii.tsms.modules.data.service.TeamService | |||
import com.ffii.tsms.modules.project.entity.* | |||
@@ -35,11 +33,13 @@ import java.time.LocalDate | |||
import java.net.URLEncoder | |||
import java.time.format.DateTimeFormatter | |||
import org.springframework.stereotype.Controller | |||
import com.ffii.tsms.modules.data.entity.TeamRepository | |||
import com.ffii.tsms.modules.data.entity.CustomerRepository | |||
import org.springframework.data.jpa.repository.JpaRepository | |||
import com.ffii.tsms.modules.project.entity.Project | |||
import com.ffii.tsms.modules.report.web.model.* | |||
import com.ffii.tsms.modules.timesheet.entity.Timesheet | |||
import org.springframework.data.domain.Example | |||
import org.springframework.data.domain.ExampleMatcher | |||
import java.time.temporal.ChronoUnit | |||
@RestController | |||
@RequestMapping("/reports") | |||
@@ -56,7 +56,8 @@ class ReportController( | |||
private val leaveRepository: LeaveRepository, | |||
private val teamService: TeamService, | |||
private val customerService: CustomerService, | |||
private val invoiceService: InvoiceService) { | |||
private val invoiceService: InvoiceService, private val gradeAllocationRepository: GradeAllocationRepository | |||
) { | |||
@PostMapping("/fetchProjectsFinancialStatusReport") | |||
@Throws(ServletRequestBindingException::class, IOException::class) | |||
@@ -87,6 +88,34 @@ class ReportController( | |||
.body(ByteArrayResource(reportResult)) | |||
} | |||
@PostMapping("/ProjectPotentialDelayReport") | |||
@Throws(ServletRequestBindingException::class, IOException::class) | |||
fun getProjectPotentialDelayReport(@RequestBody @Valid request: ProjectPotentialDelayReportRequest): ResponseEntity<Resource> { | |||
val team = if (request.teamId.lowercase() == "all") null else teamRepository.findById(request.teamId.toLong()).orElse(null) | |||
val searchedTeam = if (team == null) "All" else team.code + " - " +team.name | |||
val client = if (request.clientId.lowercase() == "all") null else customerRepository.findById(request.clientId.toLong()).orElse(null) | |||
val searchedClient = if (client == null) "All" else client.code + " - " +client.name | |||
val matcher = ExampleMatcher.matching().withIgnoreNullValues() | |||
val exampleQuery = Example.of(Project().apply { | |||
// org.springframework.dao.InvalidDataAccessApiUsageException: Path 'teamLead.team.staff' from root Project must not span a cyclic property reference | |||
// [{ com.ffii.tsms.modules.project.entity.Project@6847e037 }] -teamLead-> [{ com.ffii.tsms.modules.data.entity.Staff@2a4c488b }] -team-> [{ com.ffii.tsms.modules.data.entity.Team@a09acb5 }] -staff-> [{ com.ffii.tsms.modules.data.entity.Staff@2a4c488b }] | |||
// teamLead = team?.staff | |||
customer = client | |||
status = "On-going" | |||
}, matcher) | |||
val projects = if (team == null) projectRepository.findAll(exampleQuery) else projectRepository.findAll(exampleQuery).filter { it.teamLead == team.staff } | |||
val projectTasks = projectTaskRepository.findAllByProjectIn(projects) | |||
val timesheets = timesheetRepository.findAllByProjectTaskIn(projectTasks) | |||
val reportResult: ByteArray = excelReportService.generateProjectPotentialDelayReport(searchedTeam, searchedClient, projects, timesheets, request.numberOfDays, request.projectCompletion) | |||
return ResponseEntity.ok() | |||
.header("filename", "Project Potential Delay Report - " + LocalDate.now() + ".xlsx") | |||
.body(ByteArrayResource(reportResult)) | |||
} | |||
@PostMapping("/StaffMonthlyWorkHourAnalysisReport") | |||
@Throws(ServletRequestBindingException::class, IOException::class) | |||
fun StaffMonthlyWorkHourAnalysisReport(@RequestBody @Valid request: StaffMonthlyWorkHourAnalysisReportRequest): ResponseEntity<Resource> { | |||
@@ -262,8 +291,19 @@ class ReportController( | |||
} | |||
@GetMapping("/costNExpenses/{status}") | |||
fun getManhoursSpent(@PathVariable status: String): List<Map<String, Any?>> { | |||
return excelReportService.getCostAndExpense("All") | |||
fun getManhoursSpent(@RequestBody @Valid request: costAndExpenseRequest): List<Map<String, Any?>> { | |||
return excelReportService.getCostAndExpense(request.clientId, request.teamId) | |||
} | |||
@PostMapping("/costandexpenseReport") | |||
@Throws(ServletRequestBindingException::class, IOException::class) | |||
fun getCostAndExpenseReport(@RequestBody @Valid request: costAndExpenseRequest): ResponseEntity<Resource> { | |||
println(request) | |||
val reportResult: ByteArray = excelReportService.genCostAndExpenseReport(request) | |||
return ResponseEntity.ok() | |||
.header("filename", "Cost and Expense Report - " + LocalDate.now() + ".xlsx") | |||
.body(ByteArrayResource(reportResult)) | |||
} | |||
} |
@@ -13,11 +13,24 @@ data class PandLReportRequest ( | |||
val endMonth: String, | |||
) | |||
data class costAndExpenseRequest ( | |||
val teamId: Long?, | |||
val clientId: Long?, | |||
val budgetPercentage: Double?, | |||
) | |||
data class ProjectCashFlowReportRequest ( | |||
val projectId: Long, | |||
val dateType: String, // "Date", "Month" | |||
) | |||
data class ProjectPotentialDelayReportRequest ( | |||
val teamId: String, | |||
val clientId: String, | |||
val numberOfDays: Int, | |||
val projectCompletion: Int, | |||
) | |||
data class StaffMonthlyWorkHourAnalysisReportRequest ( | |||
val id: Long, | |||
val yearMonth: YearMonth | |||
@@ -2,6 +2,7 @@ package com.ffii.tsms.modules.timesheet.entity | |||
import com.ffii.core.entity.BaseEntity | |||
import com.ffii.tsms.modules.data.entity.Staff | |||
import com.ffii.tsms.modules.project.entity.Project | |||
import com.ffii.tsms.modules.project.entity.ProjectTask | |||
import jakarta.persistence.* | |||
import jakarta.validation.constraints.NotNull | |||
@@ -29,6 +30,10 @@ open class Timesheet : BaseEntity<Long>() { | |||
@JoinColumn(name = "projectTaskId") | |||
open var projectTask: ProjectTask? = null | |||
@ManyToOne | |||
@JoinColumn(name = "projectId") | |||
open var project: Project? = null | |||
@Column(name = "remark") | |||
open var remark: String? = null | |||
} |
@@ -46,6 +46,7 @@ open class TimesheetsService( | |||
this.normalConsumed = timeEntry.inputHours | |||
this.otConsumed = timeEntry.otHours | |||
this.projectTask = projectTask | |||
this.project = project | |||
this.remark = timeEntry.remark | |||
} | |||
} | |||
@@ -72,6 +73,7 @@ open class TimesheetsService( | |||
this.normalConsumed = entry.inputHours | |||
this.otConsumed = entry.otHours | |||
this.projectTask = projectTask | |||
this.project = project | |||
this.remark = entry.remark | |||
this.recordDate = this.recordDate ?: recordDate | |||
this.staff = this.staff ?: memberStaff | |||
@@ -112,7 +114,7 @@ open class TimesheetsService( | |||
.mapValues { (_, timesheets) -> timesheets.map { timesheet -> | |||
TimeEntry( | |||
id = timesheet.id!!, | |||
projectId = timesheet.projectTask?.project?.id, | |||
projectId = timesheet.projectTask?.project?.id ?: timesheet.project?.id, | |||
taskId = timesheet.projectTask?.task?.id, | |||
taskGroupId = timesheet.projectTask?.task?.taskGroup?.id, | |||
inputHours = timesheet.normalConsumed ?: 0.0, | |||
@@ -18,6 +18,9 @@ public class UpdateUserReq { | |||
@NotBlank | |||
private String name; | |||
@NotBlank | |||
private String username; | |||
private String firstname; | |||
private String lastname; | |||
private LocalDate expiryDate; | |||
@@ -55,6 +58,9 @@ public class UpdateUserReq { | |||
public void setName(String name) { | |||
this.name = name; | |||
} | |||
public String getUsername() { return username; } | |||
public void setUsername(String username) { this.username = username; } | |||
public LocalDate getExpiryDate() { | |||
return expiryDate; | |||
@@ -1,35 +0,0 @@ | |||
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) | |||
); |
@@ -1,114 +0,0 @@ | |||
INSERT INTO `user` (name, username, password) VALUES | |||
('Albert Lam','alam','$2a$10$65S7/AhKn8MldlYmvFN5JOfr1yaULwFNDIhTskLTuUCKgbbs8sFAi'), | |||
('Bernard Chou','bchou','$2a$10$65S7/AhKn8MldlYmvFN5JOfr1yaULwFNDIhTskLTuUCKgbbs8sFAi'), | |||
('Carl Junior','cjunior','$2a$10$65S7/AhKn8MldlYmvFN5JOfr1yaULwFNDIhTskLTuUCKgbbs8sFAi'), | |||
('Denis Lau','dlau','$2a$10$65S7/AhKn8MldlYmvFN5JOfr1yaULwFNDIhTskLTuUCKgbbs8sFAi'), | |||
('Edward Wong','ewong','$2a$10$65S7/AhKn8MldlYmvFN5JOfr1yaULwFNDIhTskLTuUCKgbbs8sFAi'), | |||
('Fred Cheung','fcheung','$2a$10$65S7/AhKn8MldlYmvFN5JOfr1yaULwFNDIhTskLTuUCKgbbs8sFAi'), | |||
('Gordon Ramsey','gramsey','$2a$10$65S7/AhKn8MldlYmvFN5JOfr1yaULwFNDIhTskLTuUCKgbbs8sFAi'), | |||
('Heather Stewards','hstewards','$2a$10$65S7/AhKn8MldlYmvFN5JOfr1yaULwFNDIhTskLTuUCKgbbs8sFAi'), | |||
('Ivan Foo','ifoo','$2a$10$65S7/AhKn8MldlYmvFN5JOfr1yaULwFNDIhTskLTuUCKgbbs8sFAi'), | |||
('Jack Son','json','$2a$10$65S7/AhKn8MldlYmvFN5JOfr1yaULwFNDIhTskLTuUCKgbbs8sFAi'), | |||
('Kurt Land','kland','$2a$10$65S7/AhKn8MldlYmvFN5JOfr1yaULwFNDIhTskLTuUCKgbbs8sFAi'), | |||
('Lawrence Arnold','larnold','$2a$10$65S7/AhKn8MldlYmvFN5JOfr1yaULwFNDIhTskLTuUCKgbbs8sFAi'); | |||
INSERT INTO staff (userId, name, staffId, companyId, teamId, salaryEffId) VALUES | |||
( | |||
(SELECT id from `user` where username = 'alam'), | |||
'Albert Lam', | |||
'003', | |||
1, | |||
1, | |||
1 | |||
), | |||
( | |||
(SELECT id from `user` where username = 'bchou'), | |||
'Bernard Chou', | |||
'004', | |||
1, | |||
2, | |||
1 | |||
), | |||
( | |||
(SELECT id from `user` where username = 'cjunior'), | |||
'Carl Junior', | |||
'005', | |||
1, | |||
1, | |||
1 | |||
), | |||
( | |||
(SELECT id from `user` where username = 'dlau'), | |||
'Denis Lau', | |||
'006', | |||
1, | |||
2, | |||
1 | |||
), | |||
( | |||
(SELECT id from `user` where username = 'ewong'), | |||
'Edward Wong', | |||
'007', | |||
1, | |||
1, | |||
1 | |||
), | |||
( | |||
(SELECT id from `user` where username = 'fcheung'), | |||
'Fred Cheung', | |||
'008', | |||
1, | |||
2, | |||
1 | |||
), | |||
( | |||
(SELECT id from `user` where username = 'gramsey'), | |||
'Gordon Ramsey', | |||
'009', | |||
1, | |||
1, | |||
1 | |||
), | |||
( | |||
(SELECT id from `user` where username = 'hstewards'), | |||
'Heather Stewards', | |||
'010', | |||
1, | |||
2, | |||
1 | |||
), | |||
( | |||
(SELECT id from `user` where username = 'ifoo'), | |||
'Ivan Foo', | |||
'011', | |||
1, | |||
1, | |||
1 | |||
), | |||
( | |||
(SELECT id from `user` where username = 'json'), | |||
'Jack Son', | |||
'012', | |||
1, | |||
2, | |||
1 | |||
), | |||
( | |||
(SELECT id from `user` where username = 'kland'), | |||
'Kurt Land', | |||
'013', | |||
1, | |||
1, | |||
1 | |||
), | |||
( | |||
(SELECT id from `user` where username = 'larnold'), | |||
'Lawrence Arnold', | |||
'014', | |||
1, | |||
2, | |||
1 | |||
); |
@@ -0,0 +1,6 @@ | |||
-- liquibase formatted sql | |||
-- changeset wayne:timesheet_project | |||
ALTER TABLE timesheet ADD projectId INT NULL; | |||
ALTER TABLE timesheet ADD CONSTRAINT FK_TIMESHEET_ON_PROJECTID FOREIGN KEY (projectId) REFERENCES project (id); |
@@ -0,0 +1,123 @@ | |||
-- liquibase formatted sql | |||
-- changeset cyril:task | |||
UPDATE task | |||
SET name='1.1 Prepare / revise Cost Estimate / Cost Plan' | |||
WHERE id=1; | |||
UPDATE task | |||
SET name='1.2 Cost estimation and cost studies' | |||
WHERE id=2; | |||
UPDATE task | |||
SET name='1.3 Cash flow forecast' | |||
WHERE id=3; | |||
UPDATE task | |||
SET name='1.4 Attend meetings' | |||
WHERE id=4; | |||
UPDATE task | |||
SET name='2.1 Advise on tendering, contractual and procurement arrangement',taskGroupId=2 | |||
WHERE id=5; | |||
UPDATE task | |||
SET name='2.2 Drafting / vetting front-part' | |||
WHERE id=6; | |||
UPDATE task | |||
SET name='2.3 Carry out pre-qualification exercise / EOI' | |||
WHERE id=7; | |||
UPDATE task | |||
SET name='2.4 Measurement & billing for 1st tender out' | |||
WHERE id=8; | |||
UPDATE task | |||
SET name='2.5 Measurement & billing for tender addendum' | |||
WHERE id=9; | |||
UPDATE task | |||
SET name='2.6 Bulk checking' | |||
WHERE id=10; | |||
UPDATE task | |||
SET name='2.7 Edit tender documents (Incl. Bills of Quantities / SOR)' | |||
WHERE id=11; | |||
UPDATE task | |||
SET name='2.8 Preparation of pre-tender estimates' | |||
WHERE id=12; | |||
UPDATE task | |||
SET name='2.9 Update cash flow forecast' | |||
WHERE id=13; | |||
UPDATE task | |||
SET name='2.10 Attend meetings' | |||
WHERE id=14; | |||
UPDATE task | |||
SET name='3.1 Evaluation of tenders (incl. rate analysis)',taskGroupId=3 | |||
WHERE id=15; | |||
UPDATE task | |||
SET name='3.2 Preparation of tender queries',taskGroupId=3 | |||
WHERE id=16; | |||
UPDATE task | |||
SET name='3.3 Attend tender interviews' | |||
WHERE id=17; | |||
UPDATE task | |||
SET name='3.4 Preparation of Report on Tenderers' | |||
WHERE id=18; | |||
UPDATE task | |||
SET name='3.5 Draft Letter of Acceptance / Award' | |||
WHERE id=19; | |||
UPDATE task | |||
SET name='3.6 Preparation of Contract Documents' | |||
WHERE id=20; | |||
UPDATE task | |||
SET name='4.1 Check insurance policies, surety bond, guarantee, etc.',taskGroupId=4 | |||
WHERE id=21; | |||
UPDATE task | |||
SET name='4.2 Valuation for interim/final payments (incl. site visits)',taskGroupId=4 | |||
WHERE id=22; | |||
UPDATE task | |||
SET name='4.3 Preparation of financial statements (incl. cash flow forecasts)',taskGroupId=4 | |||
WHERE id=23; | |||
UPDATE task | |||
SET name='4.4 Cost check / advice on alterative design solutions' | |||
WHERE id=24; | |||
UPDATE task | |||
SET name='4.5 Cost estimation for draft AIs/EIs/SIs' | |||
WHERE id=25; | |||
UPDATE task | |||
SET name='4.6 Advise on contractual issues & evaluate monetary claims' | |||
WHERE id=26; | |||
UPDATE task | |||
SET name='4.7 Measurement & valuation of variations / prime cost & provisional sums' | |||
WHERE id=27; | |||
UPDATE task | |||
SET name='4.8 Negotiation and settlement of final accounts (incl. meetings)' | |||
WHERE id=28; | |||
UPDATE task | |||
SET name='4.9 Preparation of Statement of Final Account' | |||
WHERE id=29; | |||
UPDATE task | |||
SET name='4.10 Preparation of Cost Analysis for the completed project' | |||
WHERE id=30; | |||
UPDATE task | |||
SET name='4.11 Check / review draft final bills' | |||
WHERE id=31; | |||
UPDATE task | |||
SET name='4.12 Carry out site check for draft final bills' | |||
WHERE id=32; | |||
UPDATE task | |||
SET name='4.13 Attend meetings (other than final account meetings)' | |||
WHERE id=33; | |||
UPDATE task | |||
SET name='5.1 Preparation of Fee Proposal / EOI',taskGroupId=5 | |||
WHERE id=34; | |||
UPDATE task | |||
SET name='5.2 Attend Management Meeting / Management Workshop',taskGroupId=5 | |||
WHERE id=35; | |||
UPDATE task | |||
SET name='5.3 Preparation of project budget i.e. manhours vs fee receivables',taskGroupId=5 | |||
WHERE id=36; | |||
UPDATE task | |||
SET name='5.4 Attend Local / International Conference / Seminar / Webinar' | |||
WHERE id=37; | |||
UPDATE task | |||
SET name='5.5 Preparing supplementary agreements (SA)' | |||
WHERE id=38; | |||
UPDATE task | |||
SET name='5.6 Measurement / ad hoc tasks for Contractor' | |||
WHERE id=39; | |||
UPDATE task | |||
SET name='5.7 Management Timesheet Allocation' | |||
WHERE id=40; |
@@ -0,0 +1,74 @@ | |||
-- liquibase formatted sql | |||
-- changeset cyril:position | |||
INSERT INTO position (description,name,code) | |||
VALUES ('Resident Quantity Surveyor','Resident Quantity Surveyor','Resident QS'); | |||
INSERT INTO position (description,name,code) | |||
VALUES ('Resident AQS','Resident AQS','Resident AQS'); | |||
INSERT INTO position (description,name,code) | |||
VALUES ('Administrative Officer','Administrative Officer','Admin Officer'); | |||
INSERT INTO position (description,name,code) | |||
VALUES ('Secretary','Secretary','Secretary'); | |||
INSERT INTO position (description,name,code) | |||
VALUES ('CPMS Assessor','CPMS Assessor','CPMS Assessor'); | |||
INSERT INTO position (description,name,code) | |||
VALUES ('Co-ordinator','Co-ordinator','Co-ordinator'); | |||
INSERT INTO position (description,name,code) | |||
VALUES ('Admin Supporter','Admin Supporter','Admin Supporter'); | |||
INSERT INTO position (description,name,code) | |||
VALUES ('Receptionist','Receptionist','Receptionist'); | |||
INSERT INTO position (description,name,code) | |||
VALUES ('Junior Secretary','Junior Secretary','Junior Secretary'); | |||
INSERT INTO position (description,name,code) | |||
VALUES ('Clerk','Clerk','Clerk'); | |||
INSERT INTO position (description,name,code) | |||
VALUES ('Office Assistant','Office Assistant','Office Assistant'); | |||
INSERT INTO position (description,name,code) | |||
VALUES ('HR Assistant','HR Assistant','HR Assistant'); | |||
INSERT INTO position (description,name,code) | |||
VALUES ('Project Officer','Project Officer','Project Officer'); | |||
INSERT INTO position (description,name,code) | |||
VALUES ('Ex. Secretary','Ex. Secretary','Ex. Secretary'); | |||
INSERT INTO position (description,name,code) | |||
VALUES ('I.T. Officer','I.T. Officer','I.T. Officer'); | |||
INSERT INTO position (description,name,code) | |||
VALUES ('Resident Senior Quantity Surveyor','Resident Senior Quantity Surveyor','Resident SQS'); | |||
INSERT INTO position (description,name,code) | |||
VALUES ('Obsever (SQS)','Obsever (SQS)','Obsever (SQS)'); | |||
INSERT INTO position (description,name,code) | |||
VALUES ('HR Manager','HR Manager','HR Manager'); | |||
INSERT INTO position (description,name,code) | |||
VALUES ('Senior Consultant','Senior Consultant','Senior Consultant'); | |||
UPDATE position | |||
SET description='Quantity Surveying Trainee' | |||
WHERE id=1; | |||
UPDATE position | |||
SET name='Assistant Quantity Surveyor',description='Assistant Quantity Surveyor',code='AQS' | |||
WHERE id=2; | |||
UPDATE position | |||
SET name='Quantity Surveyor',description='Quantity Surveyor' | |||
WHERE id=3; | |||
UPDATE position | |||
SET name='Senior Quantity Surveyor',description='Senior Quantity Surveyor',code='SQS' | |||
WHERE id=4; | |||
UPDATE position | |||
SET description='Assistant Manager' | |||
WHERE id=5; | |||
UPDATE position | |||
SET description='Deputy Manager' | |||
WHERE id=6; | |||
UPDATE position | |||
SET description='Manager' | |||
WHERE id=7; | |||
UPDATE position | |||
SET description='Senior Manager' | |||
WHERE id=8; | |||
UPDATE position | |||
SET description='Assistant Director' | |||
WHERE id=9; | |||
UPDATE position | |||
SET description='Deputy Director' | |||
WHERE id=10; | |||
UPDATE position | |||
SET description='Director' | |||
WHERE id=11; |