| @@ -22,5 +22,7 @@ public interface StaffRepository extends AbstractRepository<Staff, Long> { | |||||
| Optional<Staff> findByUserId(@Param("userId") Long userId); | Optional<Staff> findByUserId(@Param("userId") Long userId); | ||||
| Optional<List<Staff>> findAllByTeamIdAndDeletedFalse(Long id); | Optional<List<Staff>> findAllByTeamIdAndDeletedFalse(Long id); | ||||
| Optional<List<Staff>> findAllByDeletedFalse(); | |||||
| Optional<Staff> findIdAndNameByUserIdAndDeletedFalse(Long id); | Optional<Staff> findIdAndNameByUserIdAndDeletedFalse(Long id); | ||||
| } | } | ||||
| @@ -19,6 +19,7 @@ open class DashboardService( | |||||
| private val customerTypeRepository: CustomerTypeRepository, | private val customerTypeRepository: CustomerTypeRepository, | ||||
| private val customerSubsidiaryService: CustomerSubsidiaryService, | private val customerSubsidiaryService: CustomerSubsidiaryService, | ||||
| private val customerContactService: CustomerContactService, | private val customerContactService: CustomerContactService, | ||||
| private val staffsService: StaffsService, | |||||
| private val jdbcDao: JdbcDao | private val jdbcDao: JdbcDao | ||||
| ) { | ) { | ||||
| @@ -43,6 +44,7 @@ open class DashboardService( | |||||
| + " from customer c" | + " from customer c" | ||||
| + " left join project p on c.id = p.customerId" | + " left join project p on c.id = p.customerId" | ||||
| + " left join subsidiary s on p.customerSubsidiaryId = s.id" | + " left join subsidiary s on p.customerSubsidiaryId = s.id" | ||||
| + " left join team t on t.teamLead = p.teamLead" | |||||
| + " where c.deleted = 0" | + " where c.deleted = 0" | ||||
| + " and p.status not in (\"Pending to Start\",\"Completed\",\"Deleted\")" | + " and p.status not in (\"Pending to Start\",\"Completed\",\"Deleted\")" | ||||
| ) | ) | ||||
| @@ -52,6 +54,14 @@ open class DashboardService( | |||||
| if (args.containsKey("customerCode")) | if (args.containsKey("customerCode")) | ||||
| sql.append(" AND c.code = :customerCode"); | sql.append(" AND c.code = :customerCode"); | ||||
| } | } | ||||
| if (viewDashboardAuthority() == "self") { | |||||
| val teamId = staffsService.currentStaff()?.team?.id | |||||
| if (teamId != null) { | |||||
| sql.append(" AND t.id = $teamId") | |||||
| } | |||||
| } | |||||
| sql.append(" group by c.id, c.name, c.code, c.address, c.district, c.brNo, c.typeId, s.id, s.name, s.code, s.address, s.district, s.brNo, s.typeId"); | sql.append(" group by c.id, c.name, c.code, c.address, c.district, c.brNo, c.typeId, s.id, s.name, s.code, s.address, s.district, s.brNo, s.typeId"); | ||||
| return jdbcDao.queryForList(sql.toString(), args) | return jdbcDao.queryForList(sql.toString(), args) | ||||
| } | } | ||||
| @@ -93,9 +103,16 @@ open class DashboardService( | |||||
| + " where p.customerId = :customerId" | + " where p.customerId = :customerId" | ||||
| + " and p.customerSubsidiaryId = :subsidiaryId" | + " and p.customerSubsidiaryId = :subsidiaryId" | ||||
| + " and p.status not in (\"Pending to Start\",\"Completed\",\"Deleted\")" | + " and p.status not in (\"Pending to Start\",\"Completed\",\"Deleted\")" | ||||
| + " group by p.id, p.code, p.name, te.code, s.name, tg.name, p.totalManhour, milestonePayment.comingPaymentMilestone" | |||||
| ) | ) | ||||
| if (viewDashboardAuthority() == "self") { | |||||
| val teamId = staffsService.currentStaff()?.team?.id | |||||
| if (teamId != null) { | |||||
| sql.append(" and te.id = $teamId") | |||||
| } | |||||
| } | |||||
| sql.append(" group by p.id, p.code, p.name, te.code, s.name, tg.name, p.totalManhour, milestonePayment.comingPaymentMilestone") | |||||
| return jdbcDao.queryForList(sql.toString(), args) | return jdbcDao.queryForList(sql.toString(), args) | ||||
| } | } | ||||
| @@ -236,9 +253,16 @@ open class DashboardService( | |||||
| + " left join project p on s.id = p.teamLead" | + " left join project p on s.id = p.teamLead" | ||||
| + " where t.deleted = 0" | + " where t.deleted = 0" | ||||
| + " and p.status not in (\"Pending to Start\",\"Completed\",\"Deleted\")" | + " and p.status not in (\"Pending to Start\",\"Completed\",\"Deleted\")" | ||||
| + " group by t.id,t.teamLead,t.code,t.name" | |||||
| ) | ) | ||||
| if (viewDashboardAuthority() == "self") { | |||||
| val teamId = staffsService.currentStaff()?.team?.id | |||||
| if (teamId != null) { | |||||
| sql.append(" and t.id = $teamId") | |||||
| } | |||||
| } | |||||
| sql.append(" group by t.id,t.teamLead,t.code,t.name") | |||||
| return jdbcDao.queryForList(sql.toString(), args) | return jdbcDao.queryForList(sql.toString(), args) | ||||
| } | } | ||||
| @@ -339,6 +363,14 @@ open class DashboardService( | |||||
| + " where t.deleted = 0" | + " where t.deleted = 0" | ||||
| + " and p.status = 'On-going'" | + " and p.status = 'On-going'" | ||||
| ) | ) | ||||
| if (viewDashboardAuthority() == "self") { | |||||
| val teamId = staffsService.currentStaff()?.team?.id | |||||
| if (teamId != null) { | |||||
| sql.append(" and t.id = $teamId") | |||||
| } | |||||
| } | |||||
| sql.append(" group by t.id, t.name") | sql.append(" group by t.id, t.name") | ||||
| return jdbcDao.queryForList(sql.toString(), args) | return jdbcDao.queryForList(sql.toString(), args) | ||||
| @@ -565,6 +597,13 @@ open class DashboardService( | |||||
| + " and p.status = 'On-going'" | + " and p.status = 'On-going'" | ||||
| ) | ) | ||||
| if (viewDashboardAuthority() == "self") { | |||||
| val teamId = staffsService.currentStaff()?.team?.id | |||||
| if (teamId != null) { | |||||
| sql.append(" and t.id = $teamId") | |||||
| } | |||||
| } | |||||
| return jdbcDao.queryForList(sql.toString(), args) | return jdbcDao.queryForList(sql.toString(), args) | ||||
| } | } | ||||
| fun CashFlowMonthlyIncomeByMonth(args: Map<String, Any>): List<Map<String, Any>> { | fun CashFlowMonthlyIncomeByMonth(args: Map<String, Any>): List<Map<String, Any>> { | ||||
| @@ -977,6 +1016,13 @@ open class DashboardService( | |||||
| + " and p.deleted = 0" | + " and p.deleted = 0" | ||||
| ) | ) | ||||
| if (viewDashboardAuthority() == "self") { | |||||
| val teamLeadId = staffsService.currentStaff()?.id | |||||
| if (teamLeadId != null) { | |||||
| sql.append(" and p.teamLead = $teamLeadId") | |||||
| } | |||||
| } | |||||
| return jdbcDao.queryForList(sql.toString(), args) | return jdbcDao.queryForList(sql.toString(), args) | ||||
| } | } | ||||
| fun projectResourceSummaryInformation(args: Map<String, Any>): List<Map<String, Any>> { | fun projectResourceSummaryInformation(args: Map<String, Any>): List<Map<String, Any>> { | ||||
| @@ -1303,6 +1349,7 @@ open class DashboardService( | |||||
| + " AND dates.missing_date = ts.recordDate" | + " AND dates.missing_date = ts.recordDate" | ||||
| + " WHERE" | + " WHERE" | ||||
| + " st.teamId = :teamId" | + " st.teamId = :teamId" | ||||
| + " and st.deleted = 0" | |||||
| + " AND ts.recordDate IS NULL" | + " AND ts.recordDate IS NULL" | ||||
| + " GROUP BY" | + " GROUP BY" | ||||
| + " st.id," | + " st.id," | ||||
| @@ -1357,6 +1404,7 @@ open class DashboardService( | |||||
| + " ON st.id = ts.staffId AND dates.missing_date = ts.recordDate" | + " ON st.id = ts.staffId AND dates.missing_date = ts.recordDate" | ||||
| + " WHERE" | + " WHERE" | ||||
| + " st.teamId = :teamId" | + " st.teamId = :teamId" | ||||
| + " and st.deleted = 0" | |||||
| + " AND ts.recordDate IS NULL" | + " AND ts.recordDate IS NULL" | ||||
| + " GROUP BY" | + " GROUP BY" | ||||
| + " st.id," | + " st.id," | ||||
| @@ -1384,11 +1432,20 @@ open class DashboardService( | |||||
| + " where g.deleted = 0" | + " where g.deleted = 0" | ||||
| + " and t.recordDate >= :startdate" | + " and t.recordDate >= :startdate" | ||||
| + " and t.recordDate < DATE_FORMAT(:enddate, '%Y-%m-%d 23:59:59')" | + " and t.recordDate < DATE_FORMAT(:enddate, '%Y-%m-%d 23:59:59')" | ||||
| + " group by g.id" | |||||
| + " ) as records on records.gid = g.id" | |||||
| + " group by g.id, g.name,records.manhours" | |||||
| ) | ) | ||||
| if (viewDashboardAuthority() == "self") { | |||||
| val teamId = staffsService.currentStaff()?.team?.id | |||||
| if (teamId != null) { | |||||
| sql.append(" and s.teamId = $teamId") | |||||
| } | |||||
| } | |||||
| sql.append(" group by g.id" | |||||
| + " ) as records on records.gid = g.id" | |||||
| + " group by g.id, g.name,records.manhours") | |||||
| return jdbcDao.queryForList(sql.toString(), args) | return jdbcDao.queryForList(sql.toString(), args) | ||||
| } | } | ||||
| fun staffGradeTotalPlannedManhours(args: Map<String, Any>): List<Map<String, Any>> { | fun staffGradeTotalPlannedManhours(args: Map<String, Any>): List<Map<String, Any>> { | ||||
| @@ -1417,9 +1474,17 @@ open class DashboardService( | |||||
| + " where p.status = 'On-going'" | + " where p.status = 'On-going'" | ||||
| + " and p.planEnd > :startdate" | + " and p.planEnd > :startdate" | ||||
| + " and p.planStart < :enddate" | + " and p.planStart < :enddate" | ||||
| + " order by g.id" | |||||
| ) | ) | ||||
| if (viewDashboardAuthority() == "self") { | |||||
| val teamLeadId = staffsService.currentStaff()?.id | |||||
| if (teamLeadId != null) { | |||||
| sql.append(" and p.teamLead = $teamLeadId") | |||||
| } | |||||
| } | |||||
| sql.append(" order by g.id") | |||||
| return jdbcDao.queryForList(sql.toString(), args) | return jdbcDao.queryForList(sql.toString(), args) | ||||
| } | } | ||||
| fun IndividualStaffManhoursSpentByMonth(args: Map<String, Any>): List<Map<String, Any>> { | fun IndividualStaffManhoursSpentByMonth(args: Map<String, Any>): List<Map<String, Any>> { | ||||
| @@ -1502,7 +1567,7 @@ open class DashboardService( | |||||
| + " left join project p on sa.project_id = p.id" | + " left join project p on sa.project_id = p.id" | ||||
| + " left join timesheet t on p.id = t.projectId" | + " left join timesheet t on p.id = t.projectId" | ||||
| + " where s.id = :staffId" | + " where s.id = :staffId" | ||||
| + " and t.recordDate >= :startdate" | |||||
| + " and t.recordDate = :startdate" | |||||
| + " group by p.id, p.name" | + " group by p.id, p.name" | ||||
| + " ) as result on result.pid = p2.id" | + " ) as result on result.pid = p2.id" | ||||
| + " where s2.id = :staffId" | + " where s2.id = :staffId" | ||||
| @@ -1606,8 +1671,30 @@ open class DashboardService( | |||||
| + " where s.deleted = 0" | + " where s.deleted = 0" | ||||
| ) | ) | ||||
| if (viewDashboardAuthority() == "self") { | |||||
| val teamId = staffsService.currentStaff()?.team?.id | |||||
| if (teamId != null) { | |||||
| sql.append(" and s.teamId = $teamId") | |||||
| } | |||||
| } | |||||
| return jdbcDao.queryForList(sql.toString(), args) | return jdbcDao.queryForList(sql.toString(), args) | ||||
| } | } | ||||
| fun viewDashboardAuthority(): String { | |||||
| val authorities = staffsService.currentAuthorities() ?: return "no_authority" | |||||
| val authorityViewDashboardAll = authorities.stream().anyMatch { it.authority.equals("VIEW_DASHBOARD_ALL") } | |||||
| val authorityViewDashboardSelf = authorities.stream().anyMatch { it.authority.equals("VIEW_DASHBOARD_SELF") } | |||||
| return if (authorityViewDashboardAll) { | |||||
| "all" | |||||
| } else if (authorityViewDashboardSelf) { | |||||
| "self" | |||||
| } else { | |||||
| "no_authority" | |||||
| } | |||||
| } | |||||
| } | } | ||||
| @@ -9,6 +9,7 @@ import com.ffii.tsms.modules.data.entity.projections.StaffSearchInfo | |||||
| import com.ffii.tsms.modules.data.web.models.NewStaffRequest | import com.ffii.tsms.modules.data.web.models.NewStaffRequest | ||||
| import com.ffii.tsms.modules.user.entity.User | import com.ffii.tsms.modules.user.entity.User | ||||
| import com.ffii.tsms.modules.user.entity.UserRepository | import com.ffii.tsms.modules.user.entity.UserRepository | ||||
| import org.springframework.security.core.GrantedAuthority | |||||
| import org.springframework.security.crypto.password.PasswordEncoder | import org.springframework.security.crypto.password.PasswordEncoder | ||||
| import org.springframework.stereotype.Service | import org.springframework.stereotype.Service | ||||
| import org.springframework.transaction.annotation.Transactional | import org.springframework.transaction.annotation.Transactional | ||||
| @@ -83,6 +84,9 @@ open class StaffsService( | |||||
| return staffRepository.findAllByTeamIdAndDeletedFalse(id); | return staffRepository.findAllByTeamIdAndDeletedFalse(id); | ||||
| } | } | ||||
| open fun findAll(): Optional<List<Staff>> { | |||||
| return staffRepository.findAllByDeletedFalse() | |||||
| } | |||||
| open fun getStaff(args: Map<String, Any>): Optional<MutableMap<String, Any>>? { | open fun getStaff(args: Map<String, Any>): Optional<MutableMap<String, Any>>? { | ||||
| val sql = StringBuilder("select" | val sql = StringBuilder("select" | ||||
| + " s.id as id," | + " s.id as id," | ||||
| @@ -94,12 +98,7 @@ open class StaffsService( | |||||
| } | } | ||||
| open fun getCurrentStaff(userId: Long): Optional<MutableMap<String, Any>>? { | open fun getCurrentStaff(userId: Long): Optional<MutableMap<String, Any>>? { | ||||
| val staff = staffRepository.findByUserId(userId).orElse(null) | |||||
| logger.info(staff) | |||||
| if (staff == null) { | |||||
| return Optional.ofNullable(null) | |||||
| } | |||||
| val staff = staffRepository.findByUserId(userId).orElse(null) ?: return Optional.ofNullable(null) | |||||
| val sql = StringBuilder("select " + | val sql = StringBuilder("select " + | ||||
| " s.id as id, " + | " s.id as id, " + | ||||
| @@ -255,4 +254,8 @@ open class StaffsService( | |||||
| staffRepository.findByUserId(user.id).getOrNull() | staffRepository.findByUserId(user.id).getOrNull() | ||||
| } | } | ||||
| } | } | ||||
| open fun currentAuthorities(): Collection<GrantedAuthority>? { | |||||
| return SecurityUtils.getUser().getOrNull()?.authorities | |||||
| } | |||||
| } | } | ||||
| @@ -2,10 +2,6 @@ package com.ffii.tsms.modules.data.web | |||||
| import com.ffii.tsms.modules.data.entity.Customer | import com.ffii.tsms.modules.data.entity.Customer | ||||
| import com.ffii.tsms.modules.data.entity.CustomerType | import com.ffii.tsms.modules.data.entity.CustomerType | ||||
| import com.ffii.tsms.modules.data.service.CustomerContactService | |||||
| import com.ffii.tsms.modules.data.service.CustomerService | |||||
| import com.ffii.tsms.modules.data.service.CustomerSubsidiaryService | |||||
| import com.ffii.tsms.modules.data.service.DashboardService | |||||
| import com.ffii.tsms.modules.data.web.models.CustomerResponse | import com.ffii.tsms.modules.data.web.models.CustomerResponse | ||||
| import com.ffii.tsms.modules.data.web.models.SaveCustomerResponse | import com.ffii.tsms.modules.data.web.models.SaveCustomerResponse | ||||
| import com.ffii.tsms.modules.project.web.models.SaveCustomerRequest | import com.ffii.tsms.modules.project.web.models.SaveCustomerRequest | ||||
| @@ -22,6 +18,7 @@ import org.springframework.web.bind.annotation.DeleteMapping | |||||
| import org.springframework.web.bind.annotation.ResponseStatus | import org.springframework.web.bind.annotation.ResponseStatus | ||||
| 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.tsms.modules.data.service.* | |||||
| @RestController | @RestController | ||||
| @RequestMapping("/dashboard") | @RequestMapping("/dashboard") | ||||
| @@ -29,7 +26,8 @@ class DashboardController( | |||||
| private val customerService: CustomerService, | private val customerService: CustomerService, | ||||
| private val customerSubsidiaryService: CustomerSubsidiaryService, | private val customerSubsidiaryService: CustomerSubsidiaryService, | ||||
| private val customerContactService: CustomerContactService, | private val customerContactService: CustomerContactService, | ||||
| private val dashboardService: DashboardService | |||||
| private val dashboardService: DashboardService, | |||||
| private val staffsService: StaffsService, | |||||
| ) { | ) { | ||||
| @GetMapping("/searchCustomerSubsidiary") | @GetMapping("/searchCustomerSubsidiary") | ||||
| fun searchCustomerSubsidiary(request: HttpServletRequest?): List<Map<String, Any>> { | fun searchCustomerSubsidiary(request: HttpServletRequest?): List<Map<String, Any>> { | ||||
| @@ -94,13 +92,19 @@ class DashboardController( | |||||
| } | } | ||||
| @GetMapping("/searchFinancialSummaryCard") | @GetMapping("/searchFinancialSummaryCard") | ||||
| fun searchFinancialSummaryCard(request: HttpServletRequest?): List<Map<String, Any>> { | fun searchFinancialSummaryCard(request: HttpServletRequest?): List<Map<String, Any>> { | ||||
| val args = mutableMapOf<String, Any>() | |||||
| val allTeamCardData = dashboardService.searchFinancialSummaryAllTeamCard(args) | |||||
| val cardData = dashboardService.searchFinancialSummaryCard(args) | |||||
| val authority = dashboardService.viewDashboardAuthority() | |||||
| val args = mutableMapOf<String, Any>() | |||||
| val result = mutableListOf<Map<String, Any>>() | val result = mutableListOf<Map<String, Any>>() | ||||
| result.addAll(allTeamCardData) | |||||
| result.addAll(cardData) | |||||
| if (authority == "all") { | |||||
| val allTeamCardData = dashboardService.searchFinancialSummaryAllTeamCard(args) | |||||
| val cardData = dashboardService.searchFinancialSummaryCard(args) | |||||
| result.addAll(allTeamCardData) | |||||
| result.addAll(cardData) | |||||
| } else if (authority == "self") { | |||||
| val cardData = dashboardService.searchFinancialSummaryCard(args) | |||||
| result.addAll(cardData) | |||||
| } | |||||
| return result | return result | ||||
| } | } | ||||
| @@ -43,14 +43,9 @@ class TeamController( | |||||
| @GetMapping("/{id}") | @GetMapping("/{id}") | ||||
| fun getStaff(@PathVariable id: Long): Map<String, Any> { | fun getStaff(@PathVariable id: Long): Map<String, Any> { | ||||
| val staffList = staffsService.findAllByTeamId(id).orElseThrow { NotFoundException() } | 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 | |||||
| val staffIdList: List<Long?> = staffList.map { it.id } | |||||
| return java.util.Map.of( | return java.util.Map.of( | ||||
| "team", staffsService.find(id).orElseThrow { NotFoundException() }, | |||||
| "team", teamService.find(id).orElseThrow { NotFoundException() }, | |||||
| "staffIds", staffIdList | "staffIds", staffIdList | ||||
| ) | ) | ||||
| } | } | ||||
| @@ -21,7 +21,7 @@ data class NewStaffRequest( | |||||
| val email: String, | val email: String, | ||||
| @field:NotBlank(message = "Staff employType cannot be empty") | @field:NotBlank(message = "Staff employType cannot be empty") | ||||
| val employType: String, | val employType: String, | ||||
| @field:NotBlank(message = "Staff grade cannot be empty") | |||||
| @field:NotNull(message = "Staff grade cannot be empty") | |||||
| val gradeId: Long, | val gradeId: Long, | ||||
| val joinDate: LocalDate?, | val joinDate: LocalDate?, | ||||
| @@ -11,7 +11,7 @@ open class ProjectTask : IdEntity<Long>() { | |||||
| @ManyToOne | @ManyToOne | ||||
| open var project: Project? = null | open var project: Project? = null | ||||
| @ManyToOne(cascade = [CascadeType.ALL]) | |||||
| @ManyToOne | |||||
| @JoinColumn(name = "milestoneId") | @JoinColumn(name = "milestoneId") | ||||
| open var milestone: Milestone? = null | open var milestone: Milestone? = null | ||||
| @@ -1606,7 +1606,9 @@ open class ReportService( | |||||
| // NEW Column F: Subsidiary Name | // NEW Column F: Subsidiary Name | ||||
| val subsidiaryNameCell = row.createCell(5) | val subsidiaryNameCell = row.createCell(5) | ||||
| subsidiaryNameCell.setCellValue(data["subsidiary_name"] as String) | |||||
| // subsidiaryNameCell.setCellValue(data["subsidiary_name"] as String) | |||||
| val subsidiaryName = data["subsidiary_name"] as? String ?: "N/A" // Checks if subsidiary_name is null and replaces it with "N/A" | |||||
| subsidiaryNameCell.setCellValue(subsidiaryName) | |||||
| // Column G: Project Plan Start Date | // Column G: Project Plan Start Date | ||||
| val projectPlanStartCell = row.createCell(6) | val projectPlanStartCell = row.createCell(6) | ||||
| @@ -1745,7 +1747,7 @@ open class ReportService( | |||||
| + " min(p.code) as code, " | + " min(p.code) as code, " | ||||
| + " min(p.name) as name, " | + " min(p.name) as name, " | ||||
| + " min(t.code) as teamCode, " | + " min(t.code) as teamCode, " | ||||
| + " min(c.code) as custCode, " | |||||
| + " concat(min(c.code), ' - ', min(c.name)) as custCode, " | |||||
| + " COALESCE(concat(min(ss.code),' - ',min(ss.name)), 'N/A') as subCode, " | + " COALESCE(concat(min(ss.code),' - ',min(ss.name)), 'N/A') as subCode, " | ||||
| + " min(p.actualEnd) as actualEnd, " | + " min(p.actualEnd) as actualEnd, " | ||||
| + " min(p.expectedTotalFee) as projectFee, " | + " min(p.expectedTotalFee) as projectFee, " | ||||
| @@ -1810,8 +1812,8 @@ open class ReportService( | |||||
| + " p.code, " | + " p.code, " | ||||
| + " p.name, " | + " p.name, " | ||||
| + " t.code as team, " | + " t.code as team, " | ||||
| + " c.code as client, " | |||||
| + " COALESCE(ss.code, 'N/A') as subsidiary, " | |||||
| + " concat(c.code, ' - ', c.name) as client, " | |||||
| + " COALESCE(concat(ss.code, ' - ', ss.name), 'N/A') as subsidiary, " | |||||
| + " p.expectedTotalFee * 0.8 as plannedBudget, " | + " p.expectedTotalFee * 0.8 as plannedBudget, " | ||||
| + " COALESCE(tns.totalBudget, 0) as actualConsumedBudget, " | + " COALESCE(tns.totalBudget, 0) as actualConsumedBudget, " | ||||
| + " COALESCE(p.totalManhour, 0) as plannedManhour, " | + " COALESCE(p.totalManhour, 0) as plannedManhour, " | ||||
| @@ -57,9 +57,15 @@ open class LeaveService( | |||||
| @Transactional | @Transactional | ||||
| open fun saveMemberLeaveEntry(staffId: Long, entry: LeaveEntry, recordDate: LocalDate?): Map<String, List<LeaveEntry>> { | open fun saveMemberLeaveEntry(staffId: Long, entry: LeaveEntry, recordDate: LocalDate?): Map<String, List<LeaveEntry>> { | ||||
| val currentStaff = staffsService.currentStaff() ?: throw BadRequestException() | |||||
| // Make sure current staff is a team lead | |||||
| teamService.getMyTeamForStaff(currentStaff) ?: 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() | |||||
| val leaveTypesMap = getLeaveTypes().associateBy { it.id } | val leaveTypesMap = getLeaveTypes().associateBy { it.id } | ||||
| val memberStaff = staffsService.getStaff(staffId) | val memberStaff = staffsService.getStaff(staffId) | ||||
| @@ -87,22 +93,28 @@ open class LeaveService( | |||||
| } | } | ||||
| open fun getTeamMemberLeave(): Map<Long, TeamMemberLeaveEntries> { | open fun getTeamMemberLeave(): Map<Long, TeamMemberLeaveEntries> { | ||||
| val currentStaff = staffsService.currentStaff() ?: return emptyMap() | |||||
| // Get team where current staff is team lead | |||||
| val myTeam = teamService.getMyTeamForStaff(currentStaff) ?: return emptyMap() | |||||
| val teamMembers = staffsService.findAllByTeamId(myTeam.id!!).getOrDefault(emptyList()) | |||||
| return teamMembers.associate { member -> | |||||
| Pair( | |||||
| member.id!!, | |||||
| TeamMemberLeaveEntries( | |||||
| staffId = member.staffId, | |||||
| name = member.name, | |||||
| leaveEntries = transformToLeaveEntryMap(leaveRepository.findAllByStaff(member)) | |||||
| val authorities = staffsService.currentAuthorities() ?: return emptyMap() | |||||
| if (authorities.stream().anyMatch { it.authority.equals("MAINTAIN_TIMESHEET") }) { | |||||
| val currentStaff = staffsService.currentStaff() | |||||
| // Get team where current staff is team lead | |||||
| val myTeam = if (currentStaff != null) teamService.getMyTeamForStaff(currentStaff) else null | |||||
| val teamMembers = if (myTeam != null) { | |||||
| staffsService.findAllByTeamId(myTeam.id!!).getOrDefault(emptyList()) | |||||
| } else { | |||||
| staffsService.findAll().getOrDefault(emptyList()) | |||||
| } | |||||
| return teamMembers.associate { member -> | |||||
| Pair( | |||||
| member.id!!, | |||||
| TeamMemberLeaveEntries( | |||||
| staffId = member.staffId, | |||||
| name = member.name, | |||||
| leaveEntries = transformToLeaveEntryMap(leaveRepository.findAllByStaff(member)) | |||||
| ) | |||||
| ) | ) | ||||
| ) | |||||
| } | |||||
| } | |||||
| } else return emptyMap() | |||||
| } | } | ||||
| private fun transformToLeaveEntryMap(leaves: List<Leave>): Map<String, List<LeaveEntry>> { | private fun transformToLeaveEntryMap(leaves: List<Leave>): Map<String, List<LeaveEntry>> { | ||||
| @@ -1,6 +1,8 @@ | |||||
| package com.ffii.tsms.modules.timesheet.service | package com.ffii.tsms.modules.timesheet.service | ||||
| import com.ffii.core.exception.BadRequestException | import com.ffii.core.exception.BadRequestException | ||||
| import com.ffii.tsms.modules.data.entity.Staff | |||||
| import com.ffii.tsms.modules.data.entity.StaffRepository | |||||
| import com.ffii.tsms.modules.data.service.StaffsService | 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.project.entity.ProjectRepository | import com.ffii.tsms.modules.project.entity.ProjectRepository | ||||
| @@ -24,8 +26,8 @@ open class TimesheetsService( | |||||
| private val projectRepository: ProjectRepository, | private val projectRepository: ProjectRepository, | ||||
| private val taskRepository: TaskRepository, | private val taskRepository: TaskRepository, | ||||
| private val staffsService: StaffsService, | private val staffsService: StaffsService, | ||||
| private val teamService: TeamService | |||||
| ) { | |||||
| private val teamService: TeamService, private val staffRepository: StaffRepository | |||||
| ) { | |||||
| @Transactional | @Transactional | ||||
| open fun saveTimesheet(recordTimeEntry: Map<LocalDate, List<TimeEntry>>): Map<String, List<TimeEntry>> { | open fun saveTimesheet(recordTimeEntry: Map<LocalDate, List<TimeEntry>>): Map<String, List<TimeEntry>> { | ||||
| // Need to be associated with a staff | // Need to be associated with a staff | ||||
| @@ -59,9 +61,14 @@ open class TimesheetsService( | |||||
| @Transactional | @Transactional | ||||
| open fun saveMemberTimeEntry(staffId: Long, entry: TimeEntry, recordDate: LocalDate?): Map<String, List<TimeEntry>> { | open fun saveMemberTimeEntry(staffId: Long, entry: TimeEntry, recordDate: LocalDate?): Map<String, List<TimeEntry>> { | ||||
| val currentStaff = staffsService.currentStaff() ?: throw BadRequestException() | |||||
| // Make sure current staff is a team lead | |||||
| teamService.getMyTeamForStaff(currentStaff) ?: 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() | |||||
| val memberStaff = staffsService.getStaff(staffId) | val memberStaff = staffsService.getStaff(staffId) | ||||
| @@ -101,22 +108,29 @@ open class TimesheetsService( | |||||
| } | } | ||||
| open fun getTeamMemberTimesheet(): Map<Long, TeamMemberTimeEntries> { | open fun getTeamMemberTimesheet(): Map<Long, TeamMemberTimeEntries> { | ||||
| val currentStaff = staffsService.currentStaff() ?: return emptyMap() | |||||
| // Get team where current staff is team lead | |||||
| val myTeam = teamService.getMyTeamForStaff(currentStaff) ?: return emptyMap() | |||||
| val teamMembers = staffsService.findAllByTeamId(myTeam.id!!).getOrDefault(emptyList()) | |||||
| return teamMembers.associate { member -> | |||||
| Pair( | |||||
| member.id!!, | |||||
| TeamMemberTimeEntries( | |||||
| staffId = member.staffId, | |||||
| name = member.name, | |||||
| timeEntries = transformToTimeEntryMap(timesheetRepository.findAllByStaff(member)) | |||||
| val authorities = staffsService.currentAuthorities() ?: return emptyMap() | |||||
| if (authorities.stream().anyMatch { it.authority.equals("MAINTAIN_TIMESHEET")}) { | |||||
| val currentStaff = staffsService.currentStaff() | |||||
| // Get team where current staff is team lead | |||||
| val myTeam = if (currentStaff != null) teamService.getMyTeamForStaff(currentStaff) else null | |||||
| val teamMembers = if (myTeam != null) { | |||||
| staffsService.findAllByTeamId(myTeam.id!!).getOrDefault(emptyList()) | |||||
| } else { | |||||
| staffsService.findAll().getOrDefault(emptyList()) | |||||
| } | |||||
| return teamMembers.associate { member -> | |||||
| Pair( | |||||
| member.id!!, | |||||
| TeamMemberTimeEntries( | |||||
| staffId = member.staffId, | |||||
| name = member.name, | |||||
| timeEntries = transformToTimeEntryMap(timesheetRepository.findAllByStaff(member)) | |||||
| ) | |||||
| ) | ) | ||||
| ) | |||||
| } | |||||
| } | |||||
| } else return emptyMap() | |||||
| } | } | ||||
| private fun transformToTimeEntryMap(timesheets: List<Timesheet>): Map<String, List<TimeEntry>> { | private fun transformToTimeEntryMap(timesheets: List<Timesheet>): Map<String, List<TimeEntry>> { | ||||
| @@ -0,0 +1,8 @@ | |||||
| -- liquibase formatted sql | |||||
| -- changeset cyril:authority, user_authority | |||||
| INSERT INTO authority (authority,name) | |||||
| VALUES ('MAINTAIN_TIMESHEET_FAST_TIME_ENTRY','enter fast time entry in timesheet'); | |||||
| INSERT INTO user_authority (userId,authId) | |||||
| VALUES (1,20); | |||||