Sfoglia il codice sorgente

Merge branch 'master' of https://git.2fi-solutions.com/davidhui/TSMS-backend

tags/Baseline_30082024_BACKEND_UAT
MSI\2Fi 1 anno fa
parent
commit
7ad29fb452
11 ha cambiato i file con 201 aggiunte e 74 eliminazioni
  1. +2
    -0
      src/main/java/com/ffii/tsms/modules/data/entity/StaffRepository.java
  2. +94
    -7
      src/main/java/com/ffii/tsms/modules/data/service/DashboardService.kt
  3. +9
    -6
      src/main/java/com/ffii/tsms/modules/data/service/StaffsService.kt
  4. +14
    -10
      src/main/java/com/ffii/tsms/modules/data/web/DashboardController.kt
  5. +2
    -7
      src/main/java/com/ffii/tsms/modules/data/web/TeamController.kt
  6. +1
    -1
      src/main/java/com/ffii/tsms/modules/data/web/models/NewStaffRequest.kt
  7. +1
    -1
      src/main/java/com/ffii/tsms/modules/project/entity/ProjectTask.kt
  8. +6
    -4
      src/main/java/com/ffii/tsms/modules/report/service/ReportService.kt
  9. +30
    -18
      src/main/java/com/ffii/tsms/modules/timesheet/service/LeaveService.kt
  10. +34
    -20
      src/main/java/com/ffii/tsms/modules/timesheet/service/TimesheetsService.kt
  11. +8
    -0
      src/main/resources/db/changelog/changes/20240604_01_cyril/01_insert_authority.sql

+ 2
- 0
src/main/java/com/ffii/tsms/modules/data/entity/StaffRepository.java Vedi File

@@ -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);
} }

+ 94
- 7
src/main/java/com/ffii/tsms/modules/data/service/DashboardService.kt Vedi File

@@ -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
src/main/java/com/ffii/tsms/modules/data/service/StaffsService.kt Vedi File

@@ -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
}
} }

+ 14
- 10
src/main/java/com/ffii/tsms/modules/data/web/DashboardController.kt Vedi File

@@ -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
} }


+ 2
- 7
src/main/java/com/ffii/tsms/modules/data/web/TeamController.kt Vedi File

@@ -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
) )
} }


+ 1
- 1
src/main/java/com/ffii/tsms/modules/data/web/models/NewStaffRequest.kt Vedi File

@@ -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?,


+ 1
- 1
src/main/java/com/ffii/tsms/modules/project/entity/ProjectTask.kt Vedi File

@@ -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




+ 6
- 4
src/main/java/com/ffii/tsms/modules/report/service/ReportService.kt Vedi File

@@ -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, "


+ 30
- 18
src/main/java/com/ffii/tsms/modules/timesheet/service/LeaveService.kt Vedi File

@@ -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>> {


+ 34
- 20
src/main/java/com/ffii/tsms/modules/timesheet/service/TimesheetsService.kt Vedi File

@@ -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>> {


+ 8
- 0
src/main/resources/db/changelog/changes/20240604_01_cyril/01_insert_authority.sql Vedi File

@@ -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);

Caricamento…
Annulla
Salva