|
@@ -45,14 +45,15 @@ open class TimesheetsService( |
|
|
mergeTimeEntriesByProjectAndTask(timeEntries).map { timeEntry -> |
|
|
mergeTimeEntriesByProjectAndTask(timeEntries).map { timeEntry -> |
|
|
val task = timeEntry.taskId?.let { taskRepository.findById(it).getOrNull() } |
|
|
val task = timeEntry.taskId?.let { taskRepository.findById(it).getOrNull() } |
|
|
val project = timeEntry.projectId?.let { projectRepository.findById(it).getOrNull() } |
|
|
val project = timeEntry.projectId?.let { projectRepository.findById(it).getOrNull() } |
|
|
val projectTask = project?.let { p -> task?.let { t -> projectTaskRepository.findByProjectAndTask(p, t) } } |
|
|
|
|
|
|
|
|
val projectTask = |
|
|
|
|
|
project?.let { p -> task?.let { t -> projectTaskRepository.findByProjectAndTask(p, t) } } |
|
|
|
|
|
|
|
|
Timesheet().apply { |
|
|
Timesheet().apply { |
|
|
this.staff = currentStaff |
|
|
this.staff = currentStaff |
|
|
this.recordDate = entryDate |
|
|
this.recordDate = entryDate |
|
|
this.normalConsumed = timeEntry.inputHours |
|
|
this.normalConsumed = timeEntry.inputHours |
|
|
this.otConsumed = timeEntry.otHours |
|
|
this.otConsumed = timeEntry.otHours |
|
|
this.projectTask = projectTask |
|
|
|
|
|
|
|
|
this.projectTask = projectTask |
|
|
this.project = project |
|
|
this.project = project |
|
|
this.remark = timeEntry.remark |
|
|
this.remark = timeEntry.remark |
|
|
} |
|
|
} |
|
@@ -65,7 +66,11 @@ 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 authorities = staffsService.currentAuthorities() ?: throw BadRequestException() |
|
|
val authorities = staffsService.currentAuthorities() ?: throw BadRequestException() |
|
|
|
|
|
|
|
|
if (!authorities.stream().anyMatch { it.authority.equals("MAINTAIN_TIMESHEET") }) { |
|
|
if (!authorities.stream().anyMatch { it.authority.equals("MAINTAIN_TIMESHEET") }) { |
|
@@ -80,11 +85,11 @@ open class TimesheetsService( |
|
|
val timesheet = timesheetRepository.findById(entry.id).getOrDefault(Timesheet()).apply { |
|
|
val timesheet = timesheetRepository.findById(entry.id).getOrDefault(Timesheet()).apply { |
|
|
val task = entry.taskId?.let { taskRepository.findById(it).getOrNull() } |
|
|
val task = entry.taskId?.let { taskRepository.findById(it).getOrNull() } |
|
|
val project = entry.projectId?.let { projectRepository.findById(it).getOrNull() } |
|
|
val project = entry.projectId?.let { projectRepository.findById(it).getOrNull() } |
|
|
val projectTask = project?.let { p -> task?.let { t -> projectTaskRepository.findByProjectAndTask(p, t) } } |
|
|
|
|
|
|
|
|
val projectTask = project?.let { p -> task?.let { t -> projectTaskRepository.findByProjectAndTask(p, t) } } |
|
|
|
|
|
|
|
|
this.normalConsumed = entry.inputHours |
|
|
this.normalConsumed = entry.inputHours |
|
|
this.otConsumed = entry.otHours |
|
|
this.otConsumed = entry.otHours |
|
|
this.projectTask = projectTask |
|
|
|
|
|
|
|
|
this.projectTask = projectTask |
|
|
this.project = project |
|
|
this.project = project |
|
|
this.remark = entry.remark |
|
|
this.remark = entry.remark |
|
|
this.recordDate = this.recordDate ?: recordDate |
|
|
this.recordDate = this.recordDate ?: recordDate |
|
@@ -114,7 +119,7 @@ open class TimesheetsService( |
|
|
|
|
|
|
|
|
open fun getTeamMemberTimesheet(): Map<Long, TeamMemberTimeEntries> { |
|
|
open fun getTeamMemberTimesheet(): Map<Long, TeamMemberTimeEntries> { |
|
|
val authorities = staffsService.currentAuthorities() ?: return emptyMap() |
|
|
val authorities = staffsService.currentAuthorities() ?: return emptyMap() |
|
|
if (authorities.stream().anyMatch { it.authority.equals("MAINTAIN_TIMESHEET")}) { |
|
|
|
|
|
|
|
|
if (authorities.stream().anyMatch { it.authority.equals("MAINTAIN_TIMESHEET") }) { |
|
|
val currentStaff = staffsService.currentStaff() |
|
|
val currentStaff = staffsService.currentStaff() |
|
|
// Get team where current staff is team lead |
|
|
// Get team where current staff is team lead |
|
|
|
|
|
|
|
@@ -141,27 +146,31 @@ open class TimesheetsService( |
|
|
private fun transformToTimeEntryMap(timesheets: List<Timesheet>): Map<String, List<TimeEntry>> { |
|
|
private fun transformToTimeEntryMap(timesheets: List<Timesheet>): Map<String, List<TimeEntry>> { |
|
|
return timesheets |
|
|
return timesheets |
|
|
.groupBy { timesheet -> timesheet.recordDate!!.format(DateTimeFormatter.ISO_LOCAL_DATE) } |
|
|
.groupBy { timesheet -> timesheet.recordDate!!.format(DateTimeFormatter.ISO_LOCAL_DATE) } |
|
|
.mapValues { (_, timesheets) -> timesheets.map { timesheet -> |
|
|
|
|
|
TimeEntry( |
|
|
|
|
|
id = timesheet.id!!, |
|
|
|
|
|
projectId = timesheet.projectTask?.project?.id ?: timesheet.project?.id, |
|
|
|
|
|
taskId = timesheet.projectTask?.task?.id, |
|
|
|
|
|
taskGroupId = timesheet.projectTask?.task?.taskGroup?.id, |
|
|
|
|
|
inputHours = timesheet.normalConsumed ?: 0.0, |
|
|
|
|
|
otHours = timesheet.otConsumed ?: 0.0, |
|
|
|
|
|
remark = timesheet.remark |
|
|
|
|
|
) |
|
|
|
|
|
} } |
|
|
|
|
|
|
|
|
.mapValues { (_, timesheets) -> |
|
|
|
|
|
timesheets.map { timesheet -> |
|
|
|
|
|
TimeEntry( |
|
|
|
|
|
id = timesheet.id!!, |
|
|
|
|
|
projectId = timesheet.projectTask?.project?.id ?: timesheet.project?.id, |
|
|
|
|
|
taskId = timesheet.projectTask?.task?.id, |
|
|
|
|
|
taskGroupId = timesheet.projectTask?.task?.taskGroup?.id, |
|
|
|
|
|
inputHours = timesheet.normalConsumed ?: 0.0, |
|
|
|
|
|
otHours = timesheet.otConsumed ?: 0.0, |
|
|
|
|
|
remark = timesheet.remark |
|
|
|
|
|
) |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
private fun mergeTimeEntriesByProjectAndTask(entries: List<TimeEntry>): List<TimeEntry> { |
|
|
private fun mergeTimeEntriesByProjectAndTask(entries: List<TimeEntry>): List<TimeEntry> { |
|
|
return entries |
|
|
return entries |
|
|
.groupBy { timeEntry -> Pair(timeEntry.projectId, timeEntry.taskId) } |
|
|
.groupBy { timeEntry -> Pair(timeEntry.projectId, timeEntry.taskId) } |
|
|
.values.map { timeEntries -> |
|
|
.values.map { timeEntries -> |
|
|
timeEntries.reduce { acc, timeEntry -> acc.copy( |
|
|
|
|
|
inputHours = (acc.inputHours ?: 0.0) + (timeEntry.inputHours ?: 0.0), |
|
|
|
|
|
otHours = (acc.otHours ?: 0.0) + (timeEntry.otHours ?: 0.0) |
|
|
|
|
|
) } |
|
|
|
|
|
|
|
|
timeEntries.reduce { acc, timeEntry -> |
|
|
|
|
|
acc.copy( |
|
|
|
|
|
inputHours = (acc.inputHours ?: 0.0) + (timeEntry.inputHours ?: 0.0), |
|
|
|
|
|
otHours = (acc.otHours ?: 0.0) + (timeEntry.otHours ?: 0.0) |
|
|
|
|
|
) |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@@ -173,13 +182,18 @@ open class TimesheetsService( |
|
|
return "No Excel import" // if workbook is null |
|
|
return "No Excel import" // if workbook is null |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
val notExistProjectList = mutableListOf<String>() |
|
|
val sheet: Sheet = workbook.getSheetAt(0) |
|
|
val sheet: Sheet = workbook.getSheetAt(0) |
|
|
|
|
|
|
|
|
|
|
|
logger.info("---------Start Import Timesheets-------") |
|
|
val timesheetList = mutableListOf<Timesheet>().toMutableList(); |
|
|
val timesheetList = mutableListOf<Timesheet>().toMutableList(); |
|
|
for (i in 1..<sheet.lastRowNum) { |
|
|
for (i in 1..<sheet.lastRowNum) { |
|
|
val row = sheet.getRow(i) |
|
|
val row = sheet.getRow(i) |
|
|
|
|
|
|
|
|
if (row?.getCell(0) != null && !row.getCell(0).stringCellValue.isNullOrBlank() && row.getCell(3) != null && !row.getCell(3).stringCellValue.isNullOrBlank()) { |
|
|
|
|
|
|
|
|
if (row?.getCell(0) != null && !row.getCell(0).stringCellValue.isNullOrBlank() && row.getCell(3) != null && !row.getCell( |
|
|
|
|
|
3 |
|
|
|
|
|
).stringCellValue.isNullOrBlank() |
|
|
|
|
|
) { |
|
|
logger.info("row :$i | lastCellNum" + row.lastCellNum) |
|
|
logger.info("row :$i | lastCellNum" + row.lastCellNum) |
|
|
|
|
|
|
|
|
// process staff |
|
|
// process staff |
|
@@ -193,10 +207,13 @@ open class TimesheetsService( |
|
|
logger.info("---------project-------") |
|
|
logger.info("---------project-------") |
|
|
var projectCode = StringBuilder(row.getCell(3).stringCellValue).insert(1, '-').toString() |
|
|
var projectCode = StringBuilder(row.getCell(3).stringCellValue).insert(1, '-').toString() |
|
|
|
|
|
|
|
|
if (projectCode.contains('(')) { |
|
|
|
|
|
val splitProjectCode = projectCode.split('(') |
|
|
|
|
|
val splitMainProjectCode = splitProjectCode[0].split('-') |
|
|
|
|
|
projectCode = splitMainProjectCode[0] + '-' + String.format("%04d", splitMainProjectCode[1].toInt()) + '-' + String.format("%03d", splitProjectCode[1].split(')')[0].toInt()) |
|
|
|
|
|
|
|
|
if (row.getCell(4) != null && row.getCell(4).toString().isNotBlank()) { |
|
|
|
|
|
val subCode = row.getCell(4).numericCellValue |
|
|
|
|
|
val splitMainProjectCode = projectCode.split('-') |
|
|
|
|
|
projectCode = splitMainProjectCode[0] + '-' + String.format( |
|
|
|
|
|
"%04d", |
|
|
|
|
|
splitMainProjectCode[1].toInt() |
|
|
|
|
|
) + '-' + String.format("%03d", subCode.toInt()) |
|
|
} else { |
|
|
} else { |
|
|
val splitProjectCode = projectCode.split('-') |
|
|
val splitProjectCode = projectCode.split('-') |
|
|
projectCode = splitProjectCode[0] + '-' + String.format("%04d", splitProjectCode[1].toInt()) |
|
|
projectCode = splitProjectCode[0] + '-' + String.format("%04d", splitProjectCode[1].toInt()) |
|
@@ -208,7 +225,8 @@ open class TimesheetsService( |
|
|
// process project task |
|
|
// process project task |
|
|
logger.info("---------project task-------") |
|
|
logger.info("---------project task-------") |
|
|
val task = taskRepository.findById(41).getOrNull() |
|
|
val task = taskRepository.findById(41).getOrNull() |
|
|
val projectTask = project?.let { p -> task?.let { t -> projectTaskRepository.findByProjectAndTask(p, t) } } |
|
|
|
|
|
|
|
|
val projectTask = |
|
|
|
|
|
project?.let { p -> task?.let { t -> projectTaskRepository.findByProjectAndTask(p, t) } } |
|
|
|
|
|
|
|
|
// process record date |
|
|
// process record date |
|
|
logger.info("---------record date-------") |
|
|
logger.info("---------record date-------") |
|
@@ -221,20 +239,25 @@ open class TimesheetsService( |
|
|
val normalHours = if (hours > 8.0) 8.0 else hours |
|
|
val normalHours = if (hours > 8.0) 8.0 else hours |
|
|
val otHours = if (hours > 8.0) hours - 8.0 else 0.0 |
|
|
val otHours = if (hours > 8.0) hours - 8.0 else 0.0 |
|
|
|
|
|
|
|
|
timesheetList += Timesheet().apply { |
|
|
|
|
|
this.staff = staff |
|
|
|
|
|
this.recordDate = recordDate |
|
|
|
|
|
this.normalConsumed = normalHours |
|
|
|
|
|
this.otConsumed = otHours |
|
|
|
|
|
this.projectTask = projectTask |
|
|
|
|
|
this.project = project |
|
|
|
|
|
|
|
|
if (project != null) { |
|
|
|
|
|
timesheetList += Timesheet().apply { |
|
|
|
|
|
this.staff = staff |
|
|
|
|
|
this.recordDate = recordDate |
|
|
|
|
|
this.normalConsumed = normalHours |
|
|
|
|
|
this.otConsumed = otHours |
|
|
|
|
|
this.projectTask = projectTask |
|
|
|
|
|
this.project = project |
|
|
|
|
|
} |
|
|
|
|
|
} else { |
|
|
|
|
|
notExistProjectList += projectCode |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
timesheetRepository.saveAll(timesheetList) |
|
|
timesheetRepository.saveAll(timesheetList) |
|
|
logger.info("---------end-------") |
|
|
logger.info("---------end-------") |
|
|
|
|
|
logger.info("Not Exist Project List: "+ notExistProjectList.joinToString(", ")) |
|
|
|
|
|
|
|
|
return if (sheet.lastRowNum > 0) "Import Excel success" else "Import Excel failure" |
|
|
|
|
|
|
|
|
return if (sheet.lastRowNum > 0) "Import Excel success btw " + notExistProjectList.joinToString(", ") else "Import Excel failure" |
|
|
} |
|
|
} |
|
|
} |
|
|
} |