Просмотр исходного кода

update

tags/Baseline_30082024_BACKEND_UAT
MSI\derek 1 год назад
Родитель
Сommit
3c39a7a4b1
5 измененных файлов: 145 добавлений и 0 удалений
  1. +116
    -0
      src/main/java/com/ffii/tsms/modules/report/service/ReportService.kt
  2. +24
    -0
      src/main/java/com/ffii/tsms/modules/report/web/ReportController.kt
  3. +5
    -0
      src/main/java/com/ffii/tsms/modules/report/web/model/ReportRequest.kt
  4. Двоичные данные
      src/main/resources/templates/report/AR05_Project Completion Report.xlsx
  5. Двоичные данные
      src/main/resources/templates/report/AR06_Project Completion Report with Outstanding Accounts Receivable v02.xlsx

+ 116
- 0
src/main/java/com/ffii/tsms/modules/report/service/ReportService.kt Просмотреть файл

@@ -20,6 +20,7 @@ import org.apache.poi.ss.util.CellAddress
import org.apache.poi.ss.util.CellRangeAddress
import org.apache.poi.ss.util.CellUtil
import org.apache.poi.xssf.usermodel.XSSFWorkbook
import org.hibernate.jdbc.Work
import org.springframework.core.io.ClassPathResource
import org.springframework.stereotype.Service
import java.io.ByteArrayOutputStream
@@ -50,6 +51,8 @@ open class ReportService(
private val SALART_LIST_TEMPLATE = "templates/report/Salary Template.xlsx"
private val LATE_START_REPORT = "templates/report/AR01_Late Start Report v01.xlsx"
private val RESOURCE_OVERCONSUMPTION_REPORT = "templates/report/AR03_Resource Overconsumption.xlsx"
private val COMPLETE_PROJECT_OUTSTANDING_RECEIVABLE = "templates/report/AR06_Project Completion Report with Outstanding Accounts Receivable v02.xlsx"
private val COMPLETION_PROJECT = "templates/report/AR05_Project Completion Report.xlsx"

// ==============================|| GENERATE REPORT ||============================== //

@@ -174,6 +177,28 @@ open class ReportService(

return outputStream.toByteArray()
}
@Throws(IOException::class)
fun generateProjectCompletionReport(
args: MutableMap<String, Any>,
result: List<Map<String, Any>>
): ByteArray {
var REPORT_PATH: String = COMPLETE_PROJECT_OUTSTANDING_RECEIVABLE
if (args.get("outstanding") as Boolean == false) {
REPORT_PATH = COMPLETION_PROJECT
}
// Generate the Excel report with query results
val workbook: Workbook = createProjectCompletionReport(
args,
result,
REPORT_PATH
)
// Write the workbook to a ByteArrayOutputStream
val outputStream: ByteArrayOutputStream = ByteArrayOutputStream()
workbook.write(outputStream)
workbook.close()

return outputStream.toByteArray()
}

@Throws(IOException::class)
fun exportSalaryList(salarys: List<Salary>): ByteArray {
@@ -1061,6 +1086,49 @@ open class ReportService(

return workbook
}
private fun createProjectCompletionReport(
args: MutableMap<String, Any>,
result: List<Map<String, Any>>,
templatePath: String
): Workbook {
val resource = ClassPathResource(templatePath)
val templateInputStream = resource.inputStream
val workbook: Workbook = XSSFWorkbook(templateInputStream)

val accountingStyle = workbook.createDataFormat().getFormat("_(* #,##0.00_);_(* (#,##0.00);_(* \"-\"??_);_(@_)")
val monthStyle = workbook.createDataFormat().getFormat("MMM YYYY")
val dateStyle = workbook.createDataFormat().getFormat("dd/mm/yyyy")

val sheet: Sheet = workbook.getSheetAt(0)

var rowIndex = 1 // Assuming the location is in (1,2), which is the report date field
var columnIndex = 2
var tempRow = sheet.getRow(rowIndex)
var tempCell = tempRow.getCell(columnIndex)
tempCell.setCellValue(FORMATTED_TODAY)

rowIndex = 2
tempCell = sheet.getRow(rowIndex).getCell(columnIndex)
tempCell.setCellValue("${args.get("startDate").toString()} to ${args.get("endDate").toString()}")

rowIndex = 5
columnIndex = 0
result.forEachIndexed { index, obj ->
tempCell = sheet.getRow(rowIndex).createCell(columnIndex)
tempCell.setCellValue((index + 1).toDouble())
val keys = obj.keys.toList()
keys.forEachIndexed { keyIndex, key ->
tempCell = sheet.getRow(rowIndex).getCell(columnIndex + keyIndex + 1) ?: sheet.getRow(rowIndex).createCell(columnIndex + keyIndex + 1)
when (obj[key]) {
is Double -> tempCell.setCellValue(obj[key] as Double)
else -> tempCell.setCellValue(obj[key] as String )
}
}
rowIndex++
}
return workbook
}


private fun createProjectResourceOverconsumptionReport(
team: String,
@@ -1273,6 +1341,54 @@ open class ReportService(
)
return jdbcDao.queryForList(sql.toString(), args)
}
open fun getProjectCompletionReport(args: Map<String, Any>): List<Map<String, Any>> {
val sql = StringBuilder("select"
+ " result.code, "
+ " result.name, "
+ " result.teamCode, "
+ " result.custCode, " )
if (args.get("outstanding") as Boolean) {
sql.append(" result.totalBudget - COALESCE(i.issueAmount , 0) + COALESCE(i.issueAmount, 0) - COALESCE(i.paidAmount, 0) as `Receivable Remained`, ")
}
sql.append(
" DATE_FORMAT(result.actualEnd, '%d/%m/%Y') as actualEnd "
+ " from ( "
+ " SELECT "
+ " pt.project_id, "
+ " min(p.code) as code, "
+ " min(p.name) as name, "
+ " min(t.code) as teamCode, "
+ " min(c.code) as custCode, "
+ " min(p.actualEnd) as actualEnd, "
+ " sum(COALESCE(tns.totalConsumed*sal.hourlyRate, 0)) as totalBudget "
+ " FROM ( "
+ " SELECT "
+ " t.staffId, "
+ " sum(t.normalConsumed + COALESCE(t.otConsumed, 0)) as totalConsumed, "
+ " t.projectTaskId AS taskId "
+ " FROM timesheet t "
+ " LEFT JOIN staff s ON t.staffId = s.id "
+ " LEFT JOIN team te on s.teamId = te.id "
+ " GROUP BY t.staffId, t.projectTaskId "
+ " order by t.staffId "
+ " ) AS tns "
+ " inner join project_task pt ON tns.taskId = pt.id "
+ " left JOIN staff s ON tns.staffId = s.id "
+ " left join salary sal on s.salaryId = sal.salaryPoint "
+ " left JOIN team t ON s.teamId = t.id "
+ " left join project p on p.id = pt.project_id "
+ " left join customer c on c.id = p.customerId "
+ " where p.deleted = false "
+ " and p.status = 'Completed' "
+ " and p.actualEnd BETWEEN :startDate and :endDate "
+ " group by pt.project_id "
+ " ) as result "
+ " left join invoice i on result.code = i.projectCode "
+ " order by result.actualEnd "
)

return jdbcDao.queryForList(sql.toString(), args)
}

open fun getProjectResourceOverconsumptionReport(args: Map<String, Any>): List<Map<String, Any>> {
val sql = StringBuilder("WITH teamNormalConsumed AS ("


+ 24
- 0
src/main/java/com/ffii/tsms/modules/report/web/ReportController.kt Просмотреть файл

@@ -141,6 +141,30 @@ class ReportController(
.body(ByteArrayResource(reportResult))
}

@PostMapping("/ProjectCompletionReportwithOutstandingAccountsReceivable")
@Throws(ServletRequestBindingException::class, IOException::class)
fun ProjectCompletionReport(@RequestBody @Valid request: ProjectCompletionReport): ResponseEntity<Resource> {
val args: MutableMap<String, Any> = mutableMapOf(
"startDate" to request.startDate,
"endDate" to request.endDate,
"outstanding" to request.outstanding
)
val result = excelReportService.getProjectCompletionReport(args);
val reportResult: ByteArray = excelReportService.generateProjectCompletionReport(args, result)
// val mediaType: MediaType = MediaType.parseMediaType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
if (request.outstanding) {
return ResponseEntity.ok()
// .contentType(mediaType)
.header("filename", "Project Completion Report with Outstanding Accounts Receivable - " + " - " + LocalDate.now() + ".xlsx")
.body(ByteArrayResource(reportResult))
}
return ResponseEntity.ok()
// .contentType(mediaType)
.header("filename", "Project Completion Report - " + " - " + LocalDate.now() + ".xlsx")
.body(ByteArrayResource(reportResult))

}

@GetMapping("/test/{id}")
fun test(@PathVariable id: Long): List<Invoice> {
val project = projectRepository.findById(id).orElseThrow()


+ 5
- 0
src/main/java/com/ffii/tsms/modules/report/web/model/ReportRequest.kt Просмотреть файл

@@ -36,4 +36,9 @@ data class ProjectResourceOverconsumptionReport (
val custId: Long?,
val status: String,
val lowerLimit: Double
)
data class ProjectCompletionReport (
val startDate: LocalDate,
val endDate: LocalDate,
val outstanding: Boolean
)

Двоичные данные
src/main/resources/templates/report/AR05_Project Completion Report.xlsx Просмотреть файл


Двоичные данные
src/main/resources/templates/report/AR06_Project Completion Report with Outstanding Accounts Receivable v02.xlsx Просмотреть файл


Загрузка…
Отмена
Сохранить