diff --git a/src/main/java/com/ffii/tsms/modules/common/SettingNames.java b/src/main/java/com/ffii/tsms/modules/common/SettingNames.java index 674e04d..cef470c 100644 --- a/src/main/java/com/ffii/tsms/modules/common/SettingNames.java +++ b/src/main/java/com/ffii/tsms/modules/common/SettingNames.java @@ -38,6 +38,8 @@ public abstract class SettingNames { public static final String MAIL_SMTP_RECIPIENTS = "MAIL.smtp.recipients"; + public static final String MAIL_SMTP_AUTH = "MAIL.smtp.auth"; + public static final String JS_VERSION = "JS.version"; public static final String REPORT_DAILYMAINT_RECIPIENTS_MECH = "REPORT.dailyMaint.recipients.mech"; diff --git a/src/main/java/com/ffii/tsms/modules/data/service/DashboardService.kt b/src/main/java/com/ffii/tsms/modules/data/service/DashboardService.kt index 9be62f5..7e18936 100644 --- a/src/main/java/com/ffii/tsms/modules/data/service/DashboardService.kt +++ b/src/main/java/com/ffii/tsms/modules/data/service/DashboardService.kt @@ -94,7 +94,8 @@ open class DashboardService( + " p.name as projectName," + " te.code as team," + " s.name as teamLead," - + " GROUP_CONCAT(DISTINCT tg.name ORDER BY tg.name) as expectedStage," +// + " GROUP_CONCAT(DISTINCT tg.name ORDER BY tg.name) as expectedStage," + + " taskGroup.expectedStage," + " p.totalManhour as budgetedManhour," + " sum(t.normalConsumed) + sum(t.otConsumed) as spentManhour," + " p.totalManhour - sum(t.normalConsumed) - sum(t.otConsumed) as remainedManhour," @@ -109,8 +110,17 @@ open class DashboardService( + " left join timesheet t on pt.id = t.projectTaskId" + " left join team te on p.teamLead = te.teamLead" + " left join staff s on te.teamLead = s.id" - + " left join milestone m on p.id = m.projectId and curdate() >= m.startDate and curdate() <= m.endDate" +// + " left join milestone m on p.id = m.projectId and curdate() >= m.startDate and curdate() <= m.endDate" +// + " left join task_group tg on m.taskGroupId = tg.id" + + " left join (" + + " select " + + " m.projectId," + + " GROUP_CONCAT(DISTINCT tg.name ORDER BY tg.name) as expectedStage" + + " from milestone m" + " left join task_group tg on m.taskGroupId = tg.id" + + " where curdate() >= m.startDate and curdate() <= m.endDate" + + " group by m.projectId" + + " ) taskGroup on p.id = taskGroup.projectId" + " left join (" + " SELECT pid, MIN(comingPaymentMilestone) AS comingPaymentMilestone" + " FROM (" @@ -139,7 +149,7 @@ open class DashboardService( } } - sql.append(" group by p.id, p.code, p.name, te.code, s.name, p.totalManhour, milestonePayment.comingPaymentMilestone") + sql.append(" group by p.id, p.code, p.name, te.code, s.name, p.totalManhour, milestonePayment.comingPaymentMilestone, taskGroup.expectedStage") if (args["tableSorting"] == "ProjectName") { sql.append(" ORDER BY p.name ASC") @@ -161,7 +171,8 @@ open class DashboardService( + " p.name as projectName," + " te.code as team," + " s.name as teamLead," - + " GROUP_CONCAT(DISTINCT tg.name ORDER BY tg.name) as expectedStage," +// + " GROUP_CONCAT(DISTINCT tg.name ORDER BY tg.name) as expectedStage," + + " taskGroup.expectedStage," + " p.totalManhour as budgetedManhour," + " COALESCE (sum(t.normalConsumed) + sum(t.otConsumed),0) as spentManhour," + " COALESCE (p.totalManhour - sum(t.normalConsumed) - sum(t.otConsumed),0) as remainedManhour," @@ -176,8 +187,17 @@ open class DashboardService( + " left join timesheet t on pt.id = t.projectTaskId" + " left join team te on p.teamLead = te.teamLead" + " left join staff s on te.teamLead = s.id" - + " left join milestone m on p.id = m.projectId and curdate() >= m.startDate and curdate() <= m.endDate" +// + " left join milestone m on p.id = m.projectId and curdate() >= m.startDate and curdate() <= m.endDate" +// + " left join task_group tg on m.taskGroupId = tg.id" + + " left join (" + + " select " + + " m.projectId," + + " GROUP_CONCAT(DISTINCT tg.name ORDER BY tg.name) as expectedStage" + + " from milestone m" + " left join task_group tg on m.taskGroupId = tg.id" + + " where curdate() >= m.startDate and curdate() <= m.endDate" + + " group by m.projectId" + + " ) taskGroup on p.id = taskGroup.projectId" + " left join (" + " SELECT pid, MIN(comingPaymentMilestone) AS comingPaymentMilestone" + " FROM (" @@ -196,7 +216,7 @@ open class DashboardService( + " and isNull(p.customerSubsidiaryId)" + " and p.status not in (\"Pending to Start\",\"Completed\",\"Deleted\")" // + " and (tg.name != '5. Miscellaneous' or tg.name is null)" - + " group by p.id, p.code, p.name, te.code, s.name, p.totalManhour, milestonePayment.comingPaymentMilestone" + + " group by p.id, p.code, p.name, te.code, s.name, p.totalManhour, milestonePayment.comingPaymentMilestone, taskGroup.expectedStage" ) if (args["tableSorting"] == "ProjectName") { sql.append(" ORDER BY p.name ASC") @@ -325,7 +345,8 @@ open class DashboardService( + " p.name as projectName," + " te.code as team," + " s.name as teamLead," - + " GROUP_CONCAT(DISTINCT tg.name ORDER BY tg.name) as expectedStage," +// + " GROUP_CONCAT(DISTINCT tg.name ORDER BY tg.name) as expectedStage," + + " taskGroup.expectedStage," + " p.totalManhour as budgetedManhour," + " COALESCE (sum(t.normalConsumed) + sum(t.otConsumed),0) as spentManhour," + " COALESCE (p.totalManhour - sum(t.normalConsumed) - sum(t.otConsumed),0) as remainedManhour," @@ -340,8 +361,17 @@ open class DashboardService( + " left join timesheet t on pt.id = t.projectTaskId" + " left join team te on p.teamLead = te.teamLead" + " left join staff s on te.teamLead = s.id" - + " left join milestone m on p.id = m.projectId and curdate() >= m.startDate and curdate() <= m.endDate" +// + " left join milestone m on p.id = m.projectId and curdate() >= m.startDate and curdate() <= m.endDate" +// + " left join task_group tg on m.taskGroupId = tg.id" + + " left join (" + + " select " + + " m.projectId," + + " GROUP_CONCAT(DISTINCT tg.name ORDER BY tg.name) as expectedStage" + + " from milestone m" + " left join task_group tg on m.taskGroupId = tg.id" + + " where curdate() >= m.startDate and curdate() <= m.endDate" + + " group by m.projectId" + + " ) taskGroup on p.id = taskGroup.projectId" + " left join (" + " SELECT pid, MIN(comingPaymentMilestone) AS comingPaymentMilestone" + " FROM (" @@ -359,7 +389,7 @@ open class DashboardService( + " where p.teamLead = :teamLeadId" + " and p.status not in (\"Pending to Start\",\"Completed\",\"Deleted\")" // + " and (tg.name != '5. Miscellaneous' or tg.name is null)" - + " group by p.id, p.code, p.name, te.code, s.name, p.totalManhour, milestonePayment.comingPaymentMilestone" + + " group by p.id, p.code, p.name, te.code, s.name, p.totalManhour, milestonePayment.comingPaymentMilestone, taskGroup.expectedStage" ) if (args["tableSorting"] == "ProjectName") { sql.append(" ORDER BY p.name ASC") @@ -409,7 +439,8 @@ open class DashboardService( + " p.name as projectName," + " te.code as team," + " s.name as teamLead," - + " GROUP_CONCAT(DISTINCT tg.name ORDER BY tg.name) as expectedStage," +// + " GROUP_CONCAT(DISTINCT tg.name ORDER BY tg.name) as expectedStage," + + " taskGroup.expectedStage," + " p.totalManhour as budgetedManhour," + " COALESCE (sum(t.normalConsumed) + sum(t.otConsumed),0) as spentManhour," + " COALESCE (p.totalManhour - sum(t.normalConsumed) - sum(t.otConsumed),0) as remainedManhour," @@ -424,8 +455,17 @@ open class DashboardService( + " left join timesheet t on pt.id = t.projectTaskId" + " left join team te on p.teamLead = te.teamLead" + " left join staff s on te.teamLead = s.id" - + " left join milestone m on p.id = m.projectId and curdate() >= m.startDate and curdate() <= m.endDate" +// + " left join milestone m on p.id = m.projectId and curdate() >= m.startDate and curdate() <= m.endDate" +// + " left join task_group tg on m.taskGroupId = tg.id" + + " left join (" + + " select " + + " m.projectId," + + " GROUP_CONCAT(DISTINCT tg.name ORDER BY tg.name) as expectedStage" + + " from milestone m" + " left join task_group tg on m.taskGroupId = tg.id" + + " where curdate() >= m.startDate and curdate() <= m.endDate" + + " group by m.projectId" + + " ) taskGroup on p.id = taskGroup.projectId" + " left join (" + " SELECT pid, MIN(comingPaymentMilestone) AS comingPaymentMilestone" + " FROM (" @@ -442,7 +482,7 @@ open class DashboardService( + " ) milestonePayment on milestonePayment.pid = p.id" + " where p.teamLead in (:teamIds)" + " and p.status not in ('Pending to Start','Completed','Deleted')" - + " group by p.id, p.code, p.name, te.code, s.name, p.totalManhour, milestonePayment.comingPaymentMilestone" + + " group by p.id, p.code, p.name, te.code, s.name, p.totalManhour, milestonePayment.comingPaymentMilestone, taskGroup.expectedStage" ) // if (args["tableSorting"] == "ProjectName") { @@ -473,7 +513,8 @@ open class DashboardService( + " p.name as projectName," + " te.code as team," + " s.name as teamLead," - + " GROUP_CONCAT(DISTINCT tg.name ORDER BY tg.name) as expectedStage," +// + " GROUP_CONCAT(DISTINCT tg.name ORDER BY tg.name) as expectedStage," + + " taskGroup.expectedStage," + " p.totalManhour as budgetedManhour," + " COALESCE (sum(t.normalConsumed) + sum(t.otConsumed),0) as spentManhour," + " COALESCE (p.totalManhour - sum(t.normalConsumed) - sum(t.otConsumed),0) as remainedManhour," @@ -488,8 +529,17 @@ open class DashboardService( + " left join timesheet t on pt.id = t.projectTaskId" + " left join team te on p.teamLead = te.teamLead" + " left join staff s on te.teamLead = s.id" - + " left join milestone m on p.id = m.projectId and curdate() >= m.startDate and curdate() <= m.endDate" +// + " left join milestone m on p.id = m.projectId and curdate() >= m.startDate and curdate() <= m.endDate" +// + " left join task_group tg on m.taskGroupId = tg.id" + + " left join (" + + " select " + + " m.projectId," + + " GROUP_CONCAT(DISTINCT tg.name ORDER BY tg.name) as expectedStage" + + " from milestone m" + " left join task_group tg on m.taskGroupId = tg.id" + + " where curdate() >= m.startDate and curdate() <= m.endDate" + + " group by m.projectId" + + " ) taskGroup on p.id = taskGroup.projectId" + " left join (" + " SELECT pid, MIN(comingPaymentMilestone) AS comingPaymentMilestone" + " FROM (" @@ -506,7 +556,7 @@ open class DashboardService( + " ) milestonePayment on milestonePayment.pid = p.id" + " where p.teamLead in (:teamIds)" + " and p.status not in ('Pending to Start','Completed','Deleted')" - + " group by p.id, p.code, p.name, te.code, s.name, p.totalManhour, milestonePayment.comingPaymentMilestone" + + " group by p.id, p.code, p.name, te.code, s.name, p.totalManhour, milestonePayment.comingPaymentMilestone, taskGroup.expectedStage" + " ORDER BY te.code ASC" ) return jdbcDao.queryForList(sql.toString(), args) @@ -540,7 +590,7 @@ open class DashboardService( + " t2.id as tid," + " count(p.id) as projectNo," + " sum(p.expectedTotalFee) as totalFee," - + " sum(round((p.expectedTotalFee - p.subContractFee) * 0.8,2)) as totalBudget" + + " sum(round((p.expectedTotalFee - ifnull(p.subContractFee, 0)) * 0.8,2)) as totalBudget" + " from team t2" + " left join project p on t2.teamLead = p.teamLead" + " where p.status = 'On-going'" @@ -601,7 +651,7 @@ open class DashboardService( + " 'All Team' as teamName," + " count(p.code) as projectNo," + " sum(p.expectedTotalFee) as totalFee," - + " round((sum(p.expectedTotalFee) - sum(p.subContractFee)) * 0.8,2) as totalBudget," + + " round((sum(p.expectedTotalFee) - sum(ifnull(p.subContractFee, 0))) * 0.8,2) as totalBudget," + " round(expenditure.cumulativeExpenditure,2) as cumulativeExpenditure," + " sum(i.issueAmount) as totalInvoiced," + " sum(p.expectedTotalFee) - sum(i.issueAmount) as unInvoiced," @@ -795,7 +845,7 @@ open class DashboardService( + " c.id as cid," + " count(p.id) as projectNo," + " sum(p.expectedTotalFee) as totalFee," - + " round((sum(p.expectedTotalFee) - sum(p.subContractFee)) * 0.8,2) as totalBudget" + + " round((sum(p.expectedTotalFee) - sum(ifnull(p.subContractFee, 0))) * 0.8,2) as totalBudget" + " from team t" + " left join project p on t.teamLead = p.teamLead" + " left join customer c on p.customerId = c.id" @@ -855,7 +905,7 @@ open class DashboardService( + " c.name as customerName," + " s3.name as subsidiaryName," + " p.expectedTotalFee as totalFee," - + " round((p.expectedTotalFee - p.subContractFee) * 0.8,2) as totalBudget," + + " round((p.expectedTotalFee - ifnull(p.subContractFee, 0)) * 0.8,2) as totalBudget," + " COALESCE(round(expenditure.cumulativeExpenditure,2),0) as cumulativeExpenditure," + " coalesce(sum(i.issueAmount),0) as totalInvoiced," + " coalesce(sum(i.paidAmount),0) as totalReceived," @@ -1060,13 +1110,13 @@ open class DashboardService( fun CashFlowReceivableAndExpenditure(args: Map): List> { val sql = StringBuilder("select" + " coalesce (round(sum(i.paidAmount)/sum(i.issueAmount)*100,0),0) as receivedPercentage," - + " coalesce (round(expenditure.expenditure/((sum(p.expectedTotalFee) - sum(p.subContractFee))*0.8)*100,0),0) as expenditurePercentage," + + " coalesce (round(expenditure.expenditure/((sum(p.expectedTotalFee) - sum(ifnull(p.subContractFee, 0)))*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) - sum(p.subContractFee))*0.8,2),0) as totalBudget," + + " coalesce (round((sum(p.expectedTotalFee) - sum(ifnull(p.subContractFee, 0)))*0.8,2),0) as totalBudget," + " coalesce (expenditure.expenditure,0) as totalExpenditure," - + " coalesce ((sum(p.expectedTotalFee) - sum(p.subContractFee))*0.8 - expenditure.expenditure,0) as expenditureReceivable," + + " coalesce ((sum(p.expectedTotalFee) - sum(ifnull(p.subContractFee, 0)))*0.8 - expenditure.expenditure,0) as expenditureReceivable," + " sum(p.expectedTotalFee) as totalProjectFee," + " coalesce (round(sum(i.issueAmount)/sum(p.expectedTotalFee)*100,0),0) as invoicedPercentage" + " from project p" @@ -1164,8 +1214,8 @@ open class DashboardService( + " 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 - p.subContractFee)*0.8 as totalBudget," - + " ((p.expectedTotalFee - p.subContractFee)*0.8) / (PERIOD_DIFF(DATE_FORMAT(p.planEnd, '%Y%m'), DATE_FORMAT(p.planStart, '%Y%m'))+1) as aniticipateExpenditure," + + " (p.expectedTotalFee - ifnull(p.subContractFee, 0))*0.8 as totalBudget," + + " ((p.expectedTotalFee - ifnull(p.subContractFee, 0))*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" @@ -1412,9 +1462,9 @@ open class DashboardService( "select" + " concat(p.code,'-',p.name) as projectCodeAndName," + " p.expectedTotalFee as totalFee," - + " (p.expectedTotalFee - p.subContractFee) * 0.8 as totalBudget," + + " (p.expectedTotalFee - ifnull(p.subContractFee, 0)) * 0.8 as totalBudget," + " coalesce (expenditure.expenditure,0) as expenditure," - + " ((p.expectedTotalFee - p.subContractFee) * 0.8) - coalesce (expenditure.expenditure,0) as remainingBudget," + + " ((p.expectedTotalFee - ifnull(p.subContractFee, 0)) * 0.8) - coalesce (expenditure.expenditure,0) as remainingBudget," + " case" + " when p.expectedTotalFee - expenditure.expenditure >= 0 then 'Within Budget'" + " when p.expectedTotalFee - expenditure.expenditure < 0 then 'Overconsumption'" diff --git a/src/main/java/com/ffii/tsms/modules/report/service/ReportService.kt b/src/main/java/com/ffii/tsms/modules/report/service/ReportService.kt index a252617..e7fef69 100644 --- a/src/main/java/com/ffii/tsms/modules/report/service/ReportService.kt +++ b/src/main/java/com/ffii/tsms/modules/report/service/ReportService.kt @@ -2094,12 +2094,12 @@ open class ReportService( + " sum(t.consumedBudget) / ((p.expectedTotalFee - ifnull(p.subContractFee, 0)) * 0.8) as budgetConsumptionRate, " + " sum(t.normalConsumed + COALESCE(t.otConsumed, 0)) / COALESCE(p.totalManhour, 0) as manhourConsumptionRate, " + " case " - + " when sum(t.consumedBudget) / ((p.expectedTotalFee - ifnull(p.subContractFee, 0)) * 0.8) >= :lowerLimit and sum(t.consumedBudget) / ((p.expectedTotalFee - ifnull(p.subContractFee, 0)) * 0.8) <= 1 " - + " or (sum(t.normalConsumed + COALESCE(t.otConsumed, 0)) / COALESCE(p.totalManhour, 0)) >= :lowerLimit and (sum(t.normalConsumed + COALESCE(t.otConsumed, 0)) / COALESCE(p.totalManhour, 0)) <= 1 " - + " then 'Potential Overconsumption' " + " when sum(t.consumedBudget) / ((p.expectedTotalFee - ifnull(p.subContractFee, 0)) * 0.8) >= 1 " + " or (sum(t.normalConsumed + COALESCE(t.otConsumed, 0)) / COALESCE(p.totalManhour, 0)) >= 1 " + " then 'Overconsumption' " + + " when sum(t.consumedBudget) / ((p.expectedTotalFee - ifnull(p.subContractFee, 0)) * 0.8) >= :lowerLimit and sum(t.consumedBudget) / ((p.expectedTotalFee - ifnull(p.subContractFee, 0)) * 0.8) <= 1 " + + " or (sum(t.normalConsumed + COALESCE(t.otConsumed, 0)) / COALESCE(p.totalManhour, 0)) >= :lowerLimit and (sum(t.normalConsumed + COALESCE(t.otConsumed, 0)) / COALESCE(p.totalManhour, 0)) <= 1 " + + " then 'Potential Overconsumption' " + " else 'Within Budget' " + " END as status " + " from " diff --git a/src/main/java/com/ffii/tsms/modules/timesheet/service/TimesheetsService.kt b/src/main/java/com/ffii/tsms/modules/timesheet/service/TimesheetsService.kt index 9abe991..d93c531 100644 --- a/src/main/java/com/ffii/tsms/modules/timesheet/service/TimesheetsService.kt +++ b/src/main/java/com/ffii/tsms/modules/timesheet/service/TimesheetsService.kt @@ -69,11 +69,11 @@ open class TimesheetsService( entry: TimeEntry, recordDate: LocalDate? ): Map> { - val authorities = staffsService.currentAuthorities() ?: throw BadRequestException() - - if (!authorities.stream().anyMatch { it.authority.equals("MAINTAIN_TIMESHEET") }) { - throw BadRequestException() - } +// val authorities = staffsService.currentAuthorities() ?: throw BadRequestException() +// +// if (!authorities.stream().anyMatch { it.authority.equals("MAINTAIN_TIMESHEET") }) { +// throw BadRequestException() +// } // val currentStaff = staffsService.currentStaff() ?: throw BadRequestException() // // Make sure current staff is a team lead // teamService.getMyTeamForStaff(currentStaff) ?: throw BadRequestException() @@ -100,9 +100,9 @@ open class TimesheetsService( } open fun deleteMemberTimeEntry(staffId: Long, entryId: Long): Map> { - val currentStaff = staffsService.currentStaff() ?: throw BadRequestException() +// val currentStaff = staffsService.currentStaff() ?: throw BadRequestException() // Make sure current staff is a team lead - teamService.getMyTeamForStaff(currentStaff) ?: throw BadRequestException() +// teamService.getMyTeamForStaff(currentStaff) ?: throw BadRequestException() val memberStaff = staffsService.getStaff(staffId) @@ -296,7 +296,7 @@ open class TimesheetsService( // normal hour + ot hour logger.info("---------normal hour + ot hour-------") - val hours: Double = row.getCell(7).numericCellValue + val hours: Double = row.getCell(8).numericCellValue val normalHours = if (hours > 8.0) 8.0 else hours val otHours = if (hours > 8.0) hours - 8.0 else 0.0 diff --git a/src/main/resources/db/changelog/changes/20240730_01_cyril/01_update_task.sql b/src/main/resources/db/changelog/changes/20240730_01_cyril/01_update_task.sql new file mode 100644 index 0000000..6e064a9 --- /dev/null +++ b/src/main/resources/db/changelog/changes/20240730_01_cyril/01_update_task.sql @@ -0,0 +1,6 @@ +-- liquibase formatted sql +-- changeset cyril:task + +UPDATE task +SET name='5.8 Internal Training' +WHERE id=41; \ No newline at end of file