# 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; | |||