# 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," | + " p.name as projectName," | ||||
+ " t.code as team," | + " t.code as team," | ||||
+ " s.name as teamLead," | + " 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," | + " c.name as client," | ||||
+ " coalesce(s2.name,'N/A') as subsidiary" | + " coalesce(s2.name,'N/A') as subsidiary" | ||||
+ " from project p" | + " from project p" | ||||
@@ -524,6 +524,390 @@ open class DashboardService( | |||||
return jdbcDao.queryForList(sql.toString(), args) | 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!! | val ids = req.addStaffIds!! | ||||
// println(ids) | // println(ids) | ||||
val teamLead = staffRepository.findById(ids[0]).orElseThrow() | 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 { | val team = Team().apply { | ||||
this.staff = teamLead | this.staff = teamLead | ||||
name = teamName | |||||
code = teamCode | |||||
name = req.name | |||||
code = req.code | |||||
description = req.description | description = req.description | ||||
} | } | ||||
teamRepository.saveAndFlush(team) | teamRepository.saveAndFlush(team) | ||||
@@ -68,26 +68,23 @@ open class TeamService( | |||||
val addIds = req.addStaffIds ?: listOf<Int>() | val addIds = req.addStaffIds ?: listOf<Int>() | ||||
val teamLead: Staff | val teamLead: Staff | ||||
val teamName: String | |||||
val teamCode: String | |||||
// val teamName: String | |||||
// val teamCode: String | |||||
if (addIds.isNotEmpty()) { | if (addIds.isNotEmpty()) { | ||||
val leader = staffRepository.findById(addIds[0].toLong()).orElseThrow() | val leader = staffRepository.findById(addIds[0].toLong()).orElseThrow() | ||||
teamName = "Team " + leader.name | |||||
// teamName = "Team " + leader.name | |||||
teamLead = leader; | 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 { | } else { | ||||
teamLead = team.staff | teamLead = team.staff | ||||
teamName = team.name | |||||
teamCode = team.code | |||||
} | } | ||||
team.apply { | team.apply { | ||||
this.staff = teamLead | this.staff = teamLead | ||||
name = teamName | |||||
code = teamCode | |||||
name = req.name | |||||
code = req.code | |||||
description = req.description | description = req.description | ||||
} | } | ||||
@@ -131,4 +131,80 @@ class DashboardController( | |||||
val args = mutableMapOf<String, Any>() | val args = mutableMapOf<String, Any>() | ||||
return dashboardService.CashFlowProject(args) | 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 | package com.ffii.tsms.modules.data.web | ||||
import com.ffii.core.exception.NotFoundException | |||||
import com.ffii.core.response.RecordsRes | import com.ffii.core.response.RecordsRes | ||||
import com.ffii.core.utils.CriteriaArgsBuilder | 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.entity.Team | ||||
import com.ffii.tsms.modules.data.service.StaffsService | |||||
import com.ffii.tsms.modules.data.service.TeamService | import com.ffii.tsms.modules.data.service.TeamService | ||||
import com.ffii.tsms.modules.data.web.models.NewTeamRequest | import com.ffii.tsms.modules.data.web.models.NewTeamRequest | ||||
import jakarta.servlet.http.HttpServletRequest | import jakarta.servlet.http.HttpServletRequest | ||||
@@ -15,7 +18,10 @@ import org.springframework.web.bind.annotation.* | |||||
@RestController | @RestController | ||||
@RequestMapping("/team") | @RequestMapping("/team") | ||||
class TeamController(private val teamService: TeamService) { | |||||
class TeamController( | |||||
private val teamService: TeamService, | |||||
private val staffsService: StaffsService, | |||||
) { | |||||
@GetMapping | @GetMapping | ||||
fun allStaff(args: Map<String, Any>): List<Map<String, Any>> { | fun allStaff(args: Map<String, Any>): List<Map<String, Any>> { | ||||
@@ -34,6 +40,21 @@ class TeamController(private val teamService: TeamService) { | |||||
return teamService.getTeamDetail(args); | 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]) | // @Transactional(rollbackFor = [Exception::class]) | ||||
@DeleteMapping("/delete/{id}") | @DeleteMapping("/delete/{id}") | ||||
@ResponseStatus(HttpStatus.NO_CONTENT) | @ResponseStatus(HttpStatus.NO_CONTENT) | ||||
@@ -13,21 +13,21 @@ data class NewStaffRequest( | |||||
val companyId: Long, | val companyId: Long, | ||||
@field:NotNull(message = "Staff salaryId cannot be empty") | @field:NotNull(message = "Staff salaryId cannot be empty") | ||||
val salaryId: Long, | val salaryId: Long, | ||||
@field:NotNull(message = "joinDate cannot be empty") | |||||
// @field:NotNull(message = "joinDate cannot be empty") | |||||
val joinDate: LocalDate, | val joinDate: LocalDate, | ||||
@field:NotNull(message = "Staff currentPositionId cannot be empty") | @field:NotNull(message = "Staff currentPositionId cannot be empty") | ||||
val currentPositionId: Long, | val currentPositionId: Long, | ||||
@field:NotNull(message = "Staff joinPositionId cannot be empty") | |||||
// @field:NotNull(message = "Staff joinPositionId cannot be empty") | |||||
val joinPositionId: Long, | val joinPositionId: Long, | ||||
@field:NotNull(message = "Staff departmentId cannot be empty") | |||||
// @field:NotNull(message = "Staff departmentId cannot be empty") | |||||
val departmentId: Long, | val departmentId: Long, | ||||
@field:NotBlank(message = "Staff phone1 cannot be empty") | @field:NotBlank(message = "Staff phone1 cannot be empty") | ||||
val phone1: String, | val phone1: String, | ||||
@field:NotBlank(message = "Staff email cannot be empty") | @field:NotBlank(message = "Staff email cannot be empty") | ||||
val email: String, | val email: String, | ||||
@field:NotBlank(message = "Staff emergContactName cannot be empty") | |||||
// @field:NotBlank(message = "Staff emergContactName cannot be empty") | |||||
val emergContactName: String, | val emergContactName: String, | ||||
@field:NotBlank(message = "Staff emergContactPhone cannot be empty") | |||||
// @field:NotBlank(message = "Staff emergContactPhone cannot be empty") | |||||
val emergContactPhone: String, | val emergContactPhone: String, | ||||
@field:NotBlank(message = "Staff employType cannot be empty") | @field:NotBlank(message = "Staff employType cannot be empty") | ||||
val employType: String, | val employType: String, | ||||
@@ -6,7 +6,8 @@ import java.time.LocalDate | |||||
data class NewTeamRequest ( | data class NewTeamRequest ( | ||||
val addStaffIds: List<Long>?, | val addStaffIds: List<Long>?, | ||||
val name: String, | |||||
val code: String, | |||||
val deleteStaffIds: List<Long>?, | val deleteStaffIds: List<Long>?, | ||||
val description: String?, | val description: String?, | ||||
val id: Long? | val id: Long? |
@@ -1,10 +1,13 @@ | |||||
package com.ffii.tsms.modules.project.entity; | package com.ffii.tsms.modules.project.entity; | ||||
import com.ffii.core.support.AbstractRepository | 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.InvoiceInfoSearchInfo | ||||
import com.ffii.tsms.modules.project.entity.projections.InvoiceSearchInfo | import com.ffii.tsms.modules.project.entity.projections.InvoiceSearchInfo | ||||
import com.ffii.tsms.modules.project.entity.projections.ProjectSearchInfo | import com.ffii.tsms.modules.project.entity.projections.ProjectSearchInfo | ||||
import org.springframework.data.jpa.repository.Query | import org.springframework.data.jpa.repository.Query | ||||
import org.springframework.lang.Nullable | |||||
import java.io.Serializable | import java.io.Serializable | ||||
import java.time.LocalDate | import java.time.LocalDate | ||||
@@ -25,8 +28,10 @@ interface ProjectRepository : AbstractRepository<Project, Long> { | |||||
"") | "") | ||||
fun getLatestCodeNumberByMainProject(isClpProject: Boolean, id: Serializable?): 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 getLatestCodeNumberBySubProject(code: String, id: Serializable?): Long? | ||||
fun findAllByStatusIsNotAndMainProjectIsNull(status: String): List<Project> | 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> { | interface ProjectTaskRepository : AbstractRepository<ProjectTask, Long> { | ||||
fun findAllByProject(project: Project): List<ProjectTask> | fun findAllByProject(project: Project): List<ProjectTask> | ||||
fun findAllByProjectIn(projects: List<Project>): List<ProjectTask> | |||||
fun findByProjectAndTask(project: Project, task: Task): 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.databind.ObjectMapper | ||||
import com.fasterxml.jackson.module.kotlin.KotlinModule | 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.FinancialStatusReportInfo | ||||
import com.ffii.tsms.modules.data.entity.projections.StaffSearchInfo | 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.CustomerService | ||||
import com.ffii.tsms.modules.data.service.TeamService | import com.ffii.tsms.modules.data.service.TeamService | ||||
import com.ffii.tsms.modules.project.entity.* | import com.ffii.tsms.modules.project.entity.* | ||||
@@ -35,11 +33,13 @@ import java.time.LocalDate | |||||
import java.net.URLEncoder | import java.net.URLEncoder | ||||
import java.time.format.DateTimeFormatter | import java.time.format.DateTimeFormatter | ||||
import org.springframework.stereotype.Controller | 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 org.springframework.data.jpa.repository.JpaRepository | ||||
import com.ffii.tsms.modules.project.entity.Project | import com.ffii.tsms.modules.project.entity.Project | ||||
import com.ffii.tsms.modules.report.web.model.* | 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 | @RestController | ||||
@RequestMapping("/reports") | @RequestMapping("/reports") | ||||
@@ -56,7 +56,8 @@ class ReportController( | |||||
private val leaveRepository: LeaveRepository, | private val leaveRepository: LeaveRepository, | ||||
private val teamService: TeamService, | private val teamService: TeamService, | ||||
private val customerService: CustomerService, | private val customerService: CustomerService, | ||||
private val invoiceService: InvoiceService) { | |||||
private val invoiceService: InvoiceService, private val gradeAllocationRepository: GradeAllocationRepository | |||||
) { | |||||
@PostMapping("/fetchProjectsFinancialStatusReport") | @PostMapping("/fetchProjectsFinancialStatusReport") | ||||
@Throws(ServletRequestBindingException::class, IOException::class) | @Throws(ServletRequestBindingException::class, IOException::class) | ||||
@@ -87,6 +88,34 @@ class ReportController( | |||||
.body(ByteArrayResource(reportResult)) | .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") | @PostMapping("/StaffMonthlyWorkHourAnalysisReport") | ||||
@Throws(ServletRequestBindingException::class, IOException::class) | @Throws(ServletRequestBindingException::class, IOException::class) | ||||
fun StaffMonthlyWorkHourAnalysisReport(@RequestBody @Valid request: StaffMonthlyWorkHourAnalysisReportRequest): ResponseEntity<Resource> { | fun StaffMonthlyWorkHourAnalysisReport(@RequestBody @Valid request: StaffMonthlyWorkHourAnalysisReportRequest): ResponseEntity<Resource> { | ||||
@@ -262,8 +291,19 @@ class ReportController( | |||||
} | } | ||||
@GetMapping("/costNExpenses/{status}") | @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, | val endMonth: String, | ||||
) | ) | ||||
data class costAndExpenseRequest ( | |||||
val teamId: Long?, | |||||
val clientId: Long?, | |||||
val budgetPercentage: Double?, | |||||
) | |||||
data class ProjectCashFlowReportRequest ( | data class ProjectCashFlowReportRequest ( | ||||
val projectId: Long, | val projectId: Long, | ||||
val dateType: String, // "Date", "Month" | val dateType: String, // "Date", "Month" | ||||
) | ) | ||||
data class ProjectPotentialDelayReportRequest ( | |||||
val teamId: String, | |||||
val clientId: String, | |||||
val numberOfDays: Int, | |||||
val projectCompletion: Int, | |||||
) | |||||
data class StaffMonthlyWorkHourAnalysisReportRequest ( | data class StaffMonthlyWorkHourAnalysisReportRequest ( | ||||
val id: Long, | val id: Long, | ||||
val yearMonth: YearMonth | val yearMonth: YearMonth | ||||
@@ -2,6 +2,7 @@ package com.ffii.tsms.modules.timesheet.entity | |||||
import com.ffii.core.entity.BaseEntity | import com.ffii.core.entity.BaseEntity | ||||
import com.ffii.tsms.modules.data.entity.Staff | 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 com.ffii.tsms.modules.project.entity.ProjectTask | ||||
import jakarta.persistence.* | import jakarta.persistence.* | ||||
import jakarta.validation.constraints.NotNull | import jakarta.validation.constraints.NotNull | ||||
@@ -29,6 +30,10 @@ open class Timesheet : BaseEntity<Long>() { | |||||
@JoinColumn(name = "projectTaskId") | @JoinColumn(name = "projectTaskId") | ||||
open var projectTask: ProjectTask? = null | open var projectTask: ProjectTask? = null | ||||
@ManyToOne | |||||
@JoinColumn(name = "projectId") | |||||
open var project: Project? = null | |||||
@Column(name = "remark") | @Column(name = "remark") | ||||
open var remark: String? = null | open var remark: String? = null | ||||
} | } |
@@ -46,6 +46,7 @@ open class TimesheetsService( | |||||
this.normalConsumed = timeEntry.inputHours | this.normalConsumed = timeEntry.inputHours | ||||
this.otConsumed = timeEntry.otHours | this.otConsumed = timeEntry.otHours | ||||
this.projectTask = projectTask | this.projectTask = projectTask | ||||
this.project = project | |||||
this.remark = timeEntry.remark | this.remark = timeEntry.remark | ||||
} | } | ||||
} | } | ||||
@@ -72,6 +73,7 @@ open class TimesheetsService( | |||||
this.normalConsumed = entry.inputHours | this.normalConsumed = entry.inputHours | ||||
this.otConsumed = entry.otHours | this.otConsumed = entry.otHours | ||||
this.projectTask = projectTask | this.projectTask = projectTask | ||||
this.project = project | |||||
this.remark = entry.remark | this.remark = entry.remark | ||||
this.recordDate = this.recordDate ?: recordDate | this.recordDate = this.recordDate ?: recordDate | ||||
this.staff = this.staff ?: memberStaff | this.staff = this.staff ?: memberStaff | ||||
@@ -112,7 +114,7 @@ open class TimesheetsService( | |||||
.mapValues { (_, timesheets) -> timesheets.map { timesheet -> | .mapValues { (_, timesheets) -> timesheets.map { timesheet -> | ||||
TimeEntry( | TimeEntry( | ||||
id = timesheet.id!!, | id = timesheet.id!!, | ||||
projectId = timesheet.projectTask?.project?.id, | |||||
projectId = timesheet.projectTask?.project?.id ?: timesheet.project?.id, | |||||
taskId = timesheet.projectTask?.task?.id, | taskId = timesheet.projectTask?.task?.id, | ||||
taskGroupId = timesheet.projectTask?.task?.taskGroup?.id, | taskGroupId = timesheet.projectTask?.task?.taskGroup?.id, | ||||
inputHours = timesheet.normalConsumed ?: 0.0, | inputHours = timesheet.normalConsumed ?: 0.0, | ||||
@@ -18,6 +18,9 @@ public class UpdateUserReq { | |||||
@NotBlank | @NotBlank | ||||
private String name; | private String name; | ||||
@NotBlank | |||||
private String username; | |||||
private String firstname; | private String firstname; | ||||
private String lastname; | private String lastname; | ||||
private LocalDate expiryDate; | private LocalDate expiryDate; | ||||
@@ -55,6 +58,9 @@ public class UpdateUserReq { | |||||
public void setName(String name) { | public void setName(String name) { | ||||
this.name = name; | this.name = name; | ||||
} | } | ||||
public String getUsername() { return username; } | |||||
public void setUsername(String username) { this.username = username; } | |||||
public LocalDate getExpiryDate() { | public LocalDate getExpiryDate() { | ||||
return expiryDate; | 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; |