| @@ -3,10 +3,12 @@ package com.ffii.tsms.config.security.jwt.web; | |||||
| import java.time.Instant; | import java.time.Instant; | ||||
| import java.util.HashSet; | import java.util.HashSet; | ||||
| import java.util.Map; | import java.util.Map; | ||||
| import java.util.Objects; | |||||
| import java.util.Set; | import java.util.Set; | ||||
| import com.ffii.tsms.modules.data.entity.Staff; | import com.ffii.tsms.modules.data.entity.Staff; | ||||
| import com.ffii.tsms.modules.data.entity.StaffRepository; | import com.ffii.tsms.modules.data.entity.StaffRepository; | ||||
| import com.ffii.tsms.modules.data.service.StaffsService; | |||||
| import com.ffii.tsms.modules.user.service.GroupService; | import com.ffii.tsms.modules.user.service.GroupService; | ||||
| import org.apache.commons.lang3.exception.ExceptionUtils; | import org.apache.commons.lang3.exception.ExceptionUtils; | ||||
| import org.springframework.beans.factory.annotation.Autowired; | import org.springframework.beans.factory.annotation.Autowired; | ||||
| @@ -58,6 +60,9 @@ public class JwtAuthenticationController { | |||||
| @Autowired | @Autowired | ||||
| private GroupService groupService; | private GroupService groupService; | ||||
| @Autowired | |||||
| private StaffsService staffsService; | |||||
| @Autowired | @Autowired | ||||
| private StaffRepository staffRepository; | private StaffRepository staffRepository; | ||||
| @@ -102,7 +107,7 @@ public class JwtAuthenticationController { | |||||
| final Map<String, Object> args = Map.of("userId", user.getId()); | final Map<String, Object> args = Map.of("userId", user.getId()); | ||||
| final String role = groupService.getGroupName(args); | final String role = groupService.getGroupName(args); | ||||
| final Staff staff = staffRepository.findIdAndNameByUserIdAndDeletedFalse(user.getId()).orElse(null); | |||||
| final Map<String, Object> staff = Objects.requireNonNull(staffsService.getCurrentStaff(user.getId())).orElse(null); | |||||
| Set<AbilityModel> abilities = new HashSet<>(); | Set<AbilityModel> abilities = new HashSet<>(); | ||||
| userAuthorityService.getUserAuthority(user).forEach(auth -> abilities.add(new AbilityModel(auth.getAuthority()))); | userAuthorityService.getUserAuthority(user).forEach(auth -> abilities.add(new AbilityModel(auth.getAuthority()))); | ||||
| @@ -1,6 +1,7 @@ | |||||
| package com.ffii.tsms.model; | package com.ffii.tsms.model; | ||||
| import java.io.Serializable; | import java.io.Serializable; | ||||
| import java.util.Map; | |||||
| import java.util.Set; | import java.util.Set; | ||||
| import com.ffii.tsms.modules.data.entity.Staff; | import com.ffii.tsms.modules.data.entity.Staff; | ||||
| @@ -16,11 +17,9 @@ public class JwtResponse implements Serializable { | |||||
| private final String refreshToken; | private final String refreshToken; | ||||
| private final String role; | private final String role; | ||||
| private final Set<AbilityModel> abilities; | private final Set<AbilityModel> abilities; | ||||
| private final Staff staff; | |||||
| private final Map<String, Object> staff; | |||||
| public JwtResponse(String accessToken, String refreshToken, String role, User user, Set<AbilityModel> abilities, Staff staff) { | |||||
| public JwtResponse(String accessToken, String refreshToken, String role, User user, Set<AbilityModel> abilities, Map<String, Object> staff) { | |||||
| this.accessToken = accessToken; | this.accessToken = accessToken; | ||||
| this.refreshToken = refreshToken; | this.refreshToken = refreshToken; | ||||
| this.role = role; | this.role = role; | ||||
| @@ -55,7 +54,7 @@ public class JwtResponse implements Serializable { | |||||
| return email; | return email; | ||||
| } | } | ||||
| public Staff getStaff() { return staff; } | |||||
| public Map<String, Object> getStaff() { return staff; } | |||||
| public Set<AbilityModel> getAbilities() { | public Set<AbilityModel> getAbilities() { | ||||
| @@ -93,6 +93,27 @@ open class StaffsService( | |||||
| return jdbcDao.queryForMap(sql.toString(), args) | return jdbcDao.queryForMap(sql.toString(), args) | ||||
| } | } | ||||
| 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 sql = StringBuilder("select " + | |||||
| " s.id as id, " + | |||||
| " t.id as teamId, " + | |||||
| " case when t.teamLead = s.id then true else false end as isTeamLead " + | |||||
| " from staff s " + | |||||
| " left join team t on t.id = s.teamId " + | |||||
| " where s.deleted = false " | |||||
| + " and s.id = " + staff.id | |||||
| ) | |||||
| return jdbcDao.queryForMap(sql.toString()) | |||||
| } | |||||
| @Transactional(rollbackFor = [Exception::class]) | @Transactional(rollbackFor = [Exception::class]) | ||||
| open fun saveStaff(req: NewStaffRequest): Staff { | open fun saveStaff(req: NewStaffRequest): Staff { | ||||
| val checkStaffIdList: List<StaffSearchInfo> = staffRepository.findStaffSearchInfoByAndDeletedFalse() | val checkStaffIdList: List<StaffSearchInfo> = staffRepository.findStaffSearchInfoByAndDeletedFalse() | ||||
| @@ -3,10 +3,12 @@ package com.ffii.tsms.modules.project.entity; | |||||
| import com.ffii.core.support.AbstractRepository | import com.ffii.core.support.AbstractRepository | ||||
| import com.ffii.tsms.modules.data.entity.Staff | import com.ffii.tsms.modules.data.entity.Staff | ||||
| import com.ffii.tsms.modules.data.entity.projections.StaffSearchInfo | import com.ffii.tsms.modules.data.entity.projections.StaffSearchInfo | ||||
| import org.springframework.data.jpa.repository.Query | |||||
| import java.time.LocalDate | import java.time.LocalDate | ||||
| interface StaffAllocationRepository : AbstractRepository<StaffAllocation, Long> { | interface StaffAllocationRepository : AbstractRepository<StaffAllocation, Long> { | ||||
| fun findAssignedProjectsByStaff(staff: Staff): List<StaffAllocation> | |||||
| @Query("SELECT sa.project FROM StaffAllocation sa WHERE sa.staff = ?1 AND sa.project.status = 'On-going'") | |||||
| fun findOnGoingAssignedProjectsByStaff(staff: Staff): List<Project> | |||||
| fun findByProject(project: Project): List<StaffAllocation> | fun findByProject(project: Project): List<StaffAllocation> | ||||
| } | } | ||||
| @@ -3,4 +3,5 @@ package com.ffii.tsms.modules.project.entity; | |||||
| import com.ffii.core.support.AbstractRepository | import com.ffii.core.support.AbstractRepository | ||||
| interface TaskTemplateRepository : AbstractRepository<TaskTemplate, Long> { | interface TaskTemplateRepository : AbstractRepository<TaskTemplate, Long> { | ||||
| fun findByCode(code: String): TaskTemplate? | |||||
| } | } | ||||
| @@ -75,29 +75,27 @@ open class ProjectsService( | |||||
| open fun allAssignedProjects(): List<AssignedProject> { | open fun allAssignedProjects(): List<AssignedProject> { | ||||
| return SecurityUtils.getUser().getOrNull()?.let { user -> | return SecurityUtils.getUser().getOrNull()?.let { user -> | ||||
| staffRepository.findByUserId(user.id).getOrNull()?.let { staff -> | staffRepository.findByUserId(user.id).getOrNull()?.let { staff -> | ||||
| staffAllocationRepository.findAssignedProjectsByStaff(staff).mapNotNull { | |||||
| it.project?.let { project -> | |||||
| val timesheetHours = timesheetRepository.totalHoursConsumedByProject(project) | |||||
| AssignedProject(id = project.id!!, | |||||
| code = project.code!!, | |||||
| name = project.name!!, | |||||
| tasks = projectTaskRepository.findAllByProject(project).mapNotNull { pt -> pt.task }, | |||||
| milestones = milestoneRepository.findAllByProject(project) | |||||
| .filter { milestone -> milestone.taskGroup?.id != null } | |||||
| .associateBy { milestone -> milestone.taskGroup!!.id!! } | |||||
| .mapValues { (_, milestone) -> | |||||
| MilestoneInfo( | |||||
| startDate = milestone.startDate?.format(DateTimeFormatter.ISO_LOCAL_DATE), | |||||
| endDate = milestone.endDate?.format(DateTimeFormatter.ISO_LOCAL_DATE) | |||||
| ) | |||||
| }, | |||||
| hoursAllocated = project.totalManhour ?: 0.0, | |||||
| hoursAllocatedOther = 0.0, | |||||
| hoursSpent = timesheetHours.normalConsumed, | |||||
| hoursSpentOther = timesheetHours.otConsumed | |||||
| ) | |||||
| } | |||||
| staffAllocationRepository.findOnGoingAssignedProjectsByStaff(staff).map { project -> | |||||
| val timesheetHours = timesheetRepository.totalHoursConsumedByProject(project) | |||||
| AssignedProject(id = project.id!!, | |||||
| code = project.code!!, | |||||
| name = project.name!!, | |||||
| tasks = projectTaskRepository.findAllByProject(project).mapNotNull { pt -> pt.task }, | |||||
| milestones = milestoneRepository.findAllByProject(project) | |||||
| .filter { milestone -> milestone.taskGroup?.id != null } | |||||
| .associateBy { milestone -> milestone.taskGroup!!.id!! } | |||||
| .mapValues { (_, milestone) -> | |||||
| MilestoneInfo( | |||||
| startDate = milestone.startDate?.format(DateTimeFormatter.ISO_LOCAL_DATE), | |||||
| endDate = milestone.endDate?.format(DateTimeFormatter.ISO_LOCAL_DATE) | |||||
| ) | |||||
| }, | |||||
| hoursAllocated = project.totalManhour ?: 0.0, | |||||
| hoursAllocatedOther = 0.0, | |||||
| hoursSpent = timesheetHours.normalConsumed, | |||||
| hoursSpentOther = timesheetHours.otConsumed | |||||
| ) | |||||
| } | } | ||||
| } | } | ||||
| } ?: emptyList() | } ?: emptyList() | ||||
| @@ -108,6 +106,7 @@ open class ProjectsService( | |||||
| ProjectWithTasks(id = project.id!!, | ProjectWithTasks(id = project.id!!, | ||||
| code = project.code!!, | code = project.code!!, | ||||
| name = project.name!!, | name = project.name!!, | ||||
| status = project.status, | |||||
| tasks = projectTaskRepository.findAllByProject(project).mapNotNull { pt -> pt.task }, | tasks = projectTaskRepository.findAllByProject(project).mapNotNull { pt -> pt.task }, | ||||
| milestones = milestoneRepository.findAllByProject(project) | milestones = milestoneRepository.findAllByProject(project) | ||||
| .filter { milestone -> milestone.taskGroup?.id != null } | .filter { milestone -> milestone.taskGroup?.id != null } | ||||
| @@ -3,10 +3,7 @@ package com.ffii.tsms.modules.project.service | |||||
| import com.ffii.core.support.JdbcDao | import com.ffii.core.support.JdbcDao | ||||
| import com.ffii.tsms.modules.data.entity.GradeRepository | import com.ffii.tsms.modules.data.entity.GradeRepository | ||||
| import com.ffii.tsms.modules.project.entity.* | import com.ffii.tsms.modules.project.entity.* | ||||
| import com.ffii.tsms.modules.project.web.models.EditTaskTemplateDetails | |||||
| import com.ffii.tsms.modules.project.web.models.NewProjectRequest | |||||
| import com.ffii.tsms.modules.project.web.models.NewTaskTemplateRequest | |||||
| import com.ffii.tsms.modules.project.web.models.TaskGroupAllocation | |||||
| import com.ffii.tsms.modules.project.web.models.* | |||||
| import org.springframework.stereotype.Service | import org.springframework.stereotype.Service | ||||
| import kotlin.jvm.optionals.getOrNull | import kotlin.jvm.optionals.getOrNull | ||||
| @@ -36,6 +33,10 @@ class TasksService( | |||||
| taskTemplateRepository.deleteById(id) | taskTemplateRepository.deleteById(id) | ||||
| } | } | ||||
| fun findTaskTemplateByCode(code: String): TaskTemplate? { | |||||
| return taskTemplateRepository.findByCode(code) | |||||
| } | |||||
| fun getTaskTemplateDetails(id: Long): EditTaskTemplateDetails? { | fun getTaskTemplateDetails(id: Long): EditTaskTemplateDetails? { | ||||
| val taskTemplate = taskTemplateRepository.findById(id) | val taskTemplate = taskTemplateRepository.findById(id) | ||||
| @@ -63,8 +64,19 @@ class TasksService( | |||||
| } | } | ||||
| } | } | ||||
| fun saveTaskTemplate(request: NewTaskTemplateRequest): TaskTemplate { | |||||
| fun saveTaskTemplate(request: NewTaskTemplateRequest): NewTaskTemplateResponse { | |||||
| val id = request.id | val id = request.id | ||||
| val duplicateTaskTemplate = findTaskTemplateByCode(request.code) | |||||
| //check duplicate customer | |||||
| if (duplicateTaskTemplate != null && duplicateTaskTemplate.id?.equals(id) == false) { | |||||
| return NewTaskTemplateResponse( | |||||
| taskTemplate = duplicateTaskTemplate, | |||||
| message = "The task template code has already existed" | |||||
| ); | |||||
| } | |||||
| val taskTemplate = if (id != null && id > 0) findTaskTemplate(id) else TaskTemplate() | val taskTemplate = if (id != null && id > 0) findTaskTemplate(id) else TaskTemplate() | ||||
| taskTemplate.apply { | taskTemplate.apply { | ||||
| this.name = request.name | this.name = request.name | ||||
| @@ -96,17 +108,13 @@ class TasksService( | |||||
| val savedTaskTemplate = taskTemplateRepository.save<TaskTemplate>(taskTemplate) | val savedTaskTemplate = taskTemplateRepository.save<TaskTemplate>(taskTemplate) | ||||
| println(taskTemplateGroupAllocationRepository.findAllByTaskTemplate(taskTemplate).size) | |||||
| println(groupAllocations.size) | |||||
| println(taskTemplateGroupAllocationRepository.findAllByTaskTemplate(taskTemplate).subtract(gradeAllocations.toSet()).size) | |||||
| taskTemplateGradeAllocationRepository.deleteAll(taskTemplateGradeAllocationRepository.findAllByTaskTemplate(taskTemplate).subtract(gradeAllocations.toSet())) | taskTemplateGradeAllocationRepository.deleteAll(taskTemplateGradeAllocationRepository.findAllByTaskTemplate(taskTemplate).subtract(gradeAllocations.toSet())) | ||||
| taskTemplateGroupAllocationRepository.deleteAll(taskTemplateGroupAllocationRepository.findAllByTaskTemplate(taskTemplate).subtract(groupAllocations.toSet())) | taskTemplateGroupAllocationRepository.deleteAll(taskTemplateGroupAllocationRepository.findAllByTaskTemplate(taskTemplate).subtract(groupAllocations.toSet())) | ||||
| taskTemplateGradeAllocationRepository.saveAll<TaskTemplateGradeAllocation>(gradeAllocations) | taskTemplateGradeAllocationRepository.saveAll<TaskTemplateGradeAllocation>(gradeAllocations) | ||||
| taskTemplateGroupAllocationRepository.saveAll<TaskTemplateGroupAllocation>(groupAllocations) | taskTemplateGroupAllocationRepository.saveAll<TaskTemplateGroupAllocation>(groupAllocations) | ||||
| return savedTaskTemplate | |||||
| return NewTaskTemplateResponse(taskTemplate = savedTaskTemplate, message = "Success"); | |||||
| } | } | ||||
| fun allTaskGroups(): List<TaskGroup> { | fun allTaskGroups(): List<TaskGroup> { | ||||
| @@ -6,6 +6,7 @@ import com.ffii.tsms.modules.project.entity.TaskTemplate | |||||
| import com.ffii.tsms.modules.project.service.TasksService | import com.ffii.tsms.modules.project.service.TasksService | ||||
| import com.ffii.tsms.modules.project.web.models.EditTaskTemplateDetails | import com.ffii.tsms.modules.project.web.models.EditTaskTemplateDetails | ||||
| import com.ffii.tsms.modules.project.web.models.NewTaskTemplateRequest | import com.ffii.tsms.modules.project.web.models.NewTaskTemplateRequest | ||||
| import com.ffii.tsms.modules.project.web.models.NewTaskTemplateResponse | |||||
| import jakarta.validation.Valid | import jakarta.validation.Valid | ||||
| import org.springframework.http.HttpStatus | import org.springframework.http.HttpStatus | ||||
| import org.springframework.web.bind.annotation.* | import org.springframework.web.bind.annotation.* | ||||
| @@ -40,7 +41,7 @@ class TasksController(private val tasksService: TasksService) { | |||||
| } | } | ||||
| @PostMapping("/templates/save") | @PostMapping("/templates/save") | ||||
| fun saveTaskTemplate(@Valid @RequestBody newTaskTemplate: NewTaskTemplateRequest): TaskTemplate { | |||||
| fun saveTaskTemplate(@Valid @RequestBody newTaskTemplate: NewTaskTemplateRequest): NewTaskTemplateResponse { | |||||
| return tasksService.saveTaskTemplate(newTaskTemplate) | return tasksService.saveTaskTemplate(newTaskTemplate) | ||||
| } | } | ||||
| } | } | ||||
| @@ -0,0 +1,8 @@ | |||||
| package com.ffii.tsms.modules.project.web.models | |||||
| import com.ffii.tsms.modules.project.entity.TaskTemplate | |||||
| data class NewTaskTemplateResponse ( | |||||
| val taskTemplate: TaskTemplate, | |||||
| val message: String, | |||||
| ) | |||||
| @@ -5,6 +5,7 @@ import com.ffii.tsms.modules.project.entity.Task | |||||
| data class ProjectWithTasks( | data class ProjectWithTasks( | ||||
| val id: Long, | val id: Long, | ||||
| val code: String, | val code: String, | ||||
| val status: String?, | |||||
| val name: String, | val name: String, | ||||
| val tasks: List<Task>, | val tasks: List<Task>, | ||||
| val milestones: Map<Long, MilestoneInfo> | val milestones: Map<Long, MilestoneInfo> | ||||
| @@ -1721,9 +1721,11 @@ open class ReportService( | |||||
| + " result.code, " | + " result.code, " | ||||
| + " result.name, " | + " result.name, " | ||||
| + " result.teamCode, " | + " result.teamCode, " | ||||
| + " result.custCode, " ) | |||||
| + " result.custCode, " | |||||
| + " result.subCode, " ) | |||||
| if (args.get("outstanding") as Boolean) { | if (args.get("outstanding") as Boolean) { | ||||
| sql.append(" result.projectFee - (result.totalBudget - COALESCE(i.issueAmount , 0) + COALESCE(i.issueAmount, 0) - COALESCE(i.paidAmount, 0)) as `Receivable Remained`, ") | |||||
| sql.append(" result.projectFee - COALESCE(i.paidAmount, 0) as `Receivable Remained`, ") | |||||
| // sql.append(" result.projectFee - (result.totalBudget - COALESCE(i.issueAmount , 0) + COALESCE(i.issueAmount, 0) - COALESCE(i.paidAmount, 0)) as `Receivable Remained`, ") | |||||
| } | } | ||||
| sql.append( | sql.append( | ||||
| " DATE_FORMAT(result.actualEnd, '%d/%m/%Y') as actualEnd " | " DATE_FORMAT(result.actualEnd, '%d/%m/%Y') as actualEnd " | ||||
| @@ -1734,6 +1736,7 @@ open class ReportService( | |||||
| + " 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, " | + " min(c.code) as custCode, " | ||||
| + " 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, " | ||||
| + " sum(COALESCE(tns.totalConsumed*sal.hourlyRate, 0)) as totalBudget " | + " sum(COALESCE(tns.totalConsumed*sal.hourlyRate, 0)) as totalBudget " | ||||
| @@ -1754,14 +1757,18 @@ open class ReportService( | |||||
| + " left join salary sal on s.salaryId = sal.salaryPoint " | + " left join salary sal on s.salaryId = sal.salaryPoint " | ||||
| + " left JOIN team t ON s.teamId = t.id " | + " left JOIN team t ON s.teamId = t.id " | ||||
| + " left join customer c on c.id = p.customerId " | + " left join customer c on c.id = p.customerId " | ||||
| + " where p.deleted = false " | |||||
| + " and p.status = 'Completed' " | |||||
| + " LEFT JOIN subsidiary ss on p.customerSubsidiaryId = ss.id " | |||||
| + " where p.deleted = false ") | |||||
| if (args.containsKey("teamId")) { | |||||
| sql.append("t.id = :teamId") | |||||
| } | |||||
| sql.append( | |||||
| " and p.status = 'Completed' " | |||||
| + " and p.actualEnd BETWEEN :startDate and :endDate " | + " and p.actualEnd BETWEEN :startDate and :endDate " | ||||
| + " group by pt.project_id " | + " group by pt.project_id " | ||||
| + " ) as result " | + " ) as result " | ||||
| + " left join invoice i on result.code = i.projectCode " | + " left join invoice i on result.code = i.projectCode " | ||||
| + " order by result.actualEnd " | |||||
| ) | |||||
| + " order by result.actualEnd ") | |||||
| return jdbcDao.queryForList(sql.toString(), args) | return jdbcDao.queryForList(sql.toString(), args) | ||||
| } | } | ||||
| @@ -1794,7 +1801,7 @@ open class ReportService( | |||||
| + " p.name, " | + " p.name, " | ||||
| + " t.code as team, " | + " t.code as team, " | ||||
| + " c.code as client, " | + " c.code as client, " | ||||
| + " COALESCE(ss.name, 'N/A') as subsidiary, " | |||||
| + " COALESCE(ss.code, '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, " | ||||
| @@ -2,9 +2,11 @@ package com.ffii.tsms.modules.report.web | |||||
| import com.fasterxml.jackson.databind.ObjectMapper | import com.fasterxml.jackson.databind.ObjectMapper | ||||
| import com.fasterxml.jackson.module.kotlin.KotlinModule | import com.fasterxml.jackson.module.kotlin.KotlinModule | ||||
| import com.ffii.tsms.modules.common.SecurityUtils | |||||
| import com.ffii.tsms.modules.data.entity.* | import com.ffii.tsms.modules.data.entity.* | ||||
| //import com.ffii.tsms.modules.data.entity.projections.FinancialStatusReportInfo | //import com.ffii.tsms.modules.data.entity.projections.FinancialStatusReportInfo | ||||
| import com.ffii.tsms.modules.data.service.CustomerService | import com.ffii.tsms.modules.data.service.CustomerService | ||||
| 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.* | import com.ffii.tsms.modules.project.entity.* | ||||
| import com.ffii.tsms.modules.project.service.InvoiceService | import com.ffii.tsms.modules.project.service.InvoiceService | ||||
| @@ -48,6 +50,7 @@ class ReportController( | |||||
| private val customerRepository: CustomerRepository, | private val customerRepository: CustomerRepository, | ||||
| private val staffRepository: StaffRepository, | private val staffRepository: StaffRepository, | ||||
| private val leaveRepository: LeaveRepository, | private val leaveRepository: LeaveRepository, | ||||
| private val staffsService: StaffsService, | |||||
| private val teamService: TeamService, | private val teamService: TeamService, | ||||
| private val customerService: CustomerService, | private val customerService: CustomerService, | ||||
| private val subsidiaryService: SubsidiaryService, | private val subsidiaryService: SubsidiaryService, | ||||
| @@ -184,6 +187,9 @@ class ReportController( | |||||
| "endDate" to request.endDate, | "endDate" to request.endDate, | ||||
| "outstanding" to request.outstanding | "outstanding" to request.outstanding | ||||
| ) | ) | ||||
| if (request.teamId != null) { | |||||
| args["teamId"] = request.teamId | |||||
| } | |||||
| val result = excelReportService.getProjectCompletionReport(args); | val result = excelReportService.getProjectCompletionReport(args); | ||||
| val reportResult: ByteArray = excelReportService.generateProjectCompletionReport(args, result) | val reportResult: ByteArray = excelReportService.generateProjectCompletionReport(args, result) | ||||
| // val mediaType: MediaType = MediaType.parseMediaType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") | // val mediaType: MediaType = MediaType.parseMediaType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") | ||||
| @@ -52,6 +52,7 @@ data class ProjectResourceOverconsumptionReport ( | |||||
| val lowerLimit: Double | val lowerLimit: Double | ||||
| ) | ) | ||||
| data class ProjectCompletionReport ( | data class ProjectCompletionReport ( | ||||
| val teamId: Long?, | |||||
| val startDate: LocalDate, | val startDate: LocalDate, | ||||
| val endDate: LocalDate, | val endDate: LocalDate, | ||||
| val outstanding: Boolean | val outstanding: Boolean | ||||