Bläddra i källkod

update report

tags/Baseline_30082024_BACKEND_UAT
cyril.tsui 1 år sedan
förälder
incheckning
9fb55c3f5a
5 ändrade filer med 42 tillägg och 12 borttagningar
  1. +2
    -0
      src/main/java/com/ffii/tsms/modules/project/entity/InvoiceRepository.kt
  2. +35
    -11
      src/main/java/com/ffii/tsms/modules/report/service/ReportService.kt
  3. +5
    -1
      src/main/java/com/ffii/tsms/modules/report/web/ReportController.kt
  4. Binär
      src/main/resources/templates/report/AR04_Cost and Expense Report v02.xlsx
  5. Binär
      src/main/resources/templates/report/AR08_Monthly Work Hours Analysis Report.xlsx

+ 2
- 0
src/main/java/com/ffii/tsms/modules/project/entity/InvoiceRepository.kt Visa fil

@@ -12,4 +12,6 @@ interface InvoiceRepository : AbstractRepository<Invoice, Long> {
fun findInvoiceInfoByPaidAmountIsNotNull(): List<InvoiceInfo>

fun findByInvoiceNo(invoiceNo: String): Invoice

fun findAllByProjectCodeAndPaidAmountIsNotNull(projectCode: String): List<Invoice>
}

+ 35
- 11
src/main/java/com/ffii/tsms/modules/report/service/ReportService.kt Visa fil

@@ -435,7 +435,8 @@ open class ReportService(
val uninvoiceCell = row.createCell(12)
uninvoiceCell.apply {
cellFormula =
" IF(I${rowNum}<=J${rowNum}, I${rowNum}-L${rowNum}, IF(AND(I${rowNum}>J${rowNum}, J${rowNum}<L${rowNum}), 0, IF(AND(I${rowNum}>J${rowNum}, J${rowNum}>=L${rowNum}), J${rowNum}-L${rowNum}, 0))) "
" IF(I${rowNum}-L${rowNum}<0, 0, I${rowNum}-L${rowNum})"
// " IF(I${rowNum}<=J${rowNum}, I${rowNum}-L${rowNum}, IF(AND(I${rowNum}>J${rowNum}, J${rowNum}<L${rowNum}), 0, IF(AND(I${rowNum}>J${rowNum}, J${rowNum}>=L${rowNum}), J${rowNum}-L${rowNum}, 0))) "
cellStyle.dataFormat = accountingStyle
}

@@ -1080,6 +1081,13 @@ open class ReportService(
val boldFont = workbook.createFont()
boldFont.bold = true
boldStyle.setFont(boldFont)

val projectsStyle = workbook.createCellStyle()
val projectsFont = workbook.createFont()
projectsFont.bold = true
projectsFont.fontName = "Times New Roman"
projectsStyle.setFont(projectsFont)

val daysOfMonth = (1..month.lengthOfMonth()).map { day ->
val date = month.withDayOfMonth(day)
val formattedDate = date.format(DateTimeFormatter.ofPattern("dd/MM/yyyy"))
@@ -1228,7 +1236,7 @@ open class ReportService(
projectList.forEachIndexed { index, title ->
tempCell = sheet.getRow(7).createCell(columnIndex + index)
tempCell.setCellValue(title)
tempCell.cellStyle = boldStyle
tempCell.cellStyle = projectsStyle
CellUtil.setAlignment(tempCell, HorizontalAlignment.CENTER)
CellUtil.setVerticalAlignment(tempCell, VerticalAlignment.CENTER)
CellUtil.setCellStyleProperties(tempCell, ThinBorderBottom)
@@ -1271,7 +1279,7 @@ open class ReportService(
///////////////////////////////////////////////////////// Leave Hours title ////////////////////////////////////////////////////////////////////
tempCell = sheet.getRow(rowIndex).createCell(columnIndex)
tempCell.setCellValue("Leave Hours")
tempCell.cellStyle = boldStyle
tempCell.cellStyle = projectsStyle
CellUtil.setVerticalAlignment(tempCell, VerticalAlignment.CENTER)
CellUtil.setAlignment(tempCell, HorizontalAlignment.CENTER)
CellUtil.setCellStyleProperties(tempCell, ThinBorderBottom)
@@ -1279,8 +1287,10 @@ open class ReportService(
columnIndex += 1
tempCell = sheet.getRow(rowIndex).createCell(columnIndex)
tempCell.setCellValue("Daily Manhour Spent\n(Excluding Leave Hours)")
tempCell.cellStyle = boldStyle
CellUtil.setAlignment(tempCell, HorizontalAlignment.LEFT)
tempCell.cellStyle = projectsStyle
// CellUtil.setAlignment(tempCell, HorizontalAlignment.LEFT)
CellUtil.setVerticalAlignment(tempCell, VerticalAlignment.CENTER)
CellUtil.setAlignment(tempCell, HorizontalAlignment.CENTER)
CellUtil.setCellStyleProperties(tempCell, ThinBorderBottom)

sheet.addMergedRegion(CellRangeAddress(6, 6, 2, columnIndex))
@@ -1375,7 +1385,7 @@ open class ReportService(
rowIndex = 5
columnIndex = 0

generalCreateReportIndexed(sheet, result, rowIndex, columnIndex)
generalCreateReportIndexed(sheet, result.distinct(), rowIndex, columnIndex)
return workbook
}

@@ -1825,12 +1835,12 @@ open class ReportService(
+ " (COALESCE((tns.totalConsumed * sa.hourlyRate), 0) / p.expectedTotalFee) as budgetConsumptionRate, "
+ " (COALESCE(tns.totalConsumed, 0) / COALESCE(p.totalManhour, 0)) as manhourConsumptionRate, "
+ " CASE "
+ " when (COALESCE((tns.totalConsumed * sa.hourlyRate), 0) / p.expectedTotalFee) >= :lowerLimit and (COALESCE((tns.totalConsumed * sa.hourlyRate), 0) / p.expectedTotalFee) <= 1 "
+ " or (COALESCE(tns.totalConsumed, 0) / COALESCE(p.totalManhour, 0)) >= :lowerLimit and (COALESCE(tns.totalConsumed, 0) / COALESCE(p.totalManhour, 0)) <= 1 "
+ " then 'Potential Overconsumption' "
+ " when (COALESCE((tns.totalConsumed * sa.hourlyRate), 0) / p.expectedTotalFee) >= 1 "
+ " or (COALESCE(tns.totalConsumed, 0) / COALESCE(p.totalManhour, 0)) >= 1 "
+ " then 'Overconsumption' "
+ " when (COALESCE((tns.totalConsumed * sa.hourlyRate), 0) / p.expectedTotalFee) >= :lowerLimit and (COALESCE((tns.totalConsumed * sa.hourlyRate), 0) / p.expectedTotalFee) <= 1 "
+ " or (COALESCE(tns.totalConsumed, 0) / COALESCE(p.totalManhour, 0)) >= :lowerLimit and (COALESCE(tns.totalConsumed, 0) / COALESCE(p.totalManhour, 0)) <= 1 "
+ " then 'Potential Overconsumption' "
+ " else 'Within Budget' "
+ " END as status "
+ " FROM project p "
@@ -1884,6 +1894,15 @@ open class ReportService(
+ " left join salary s2 on s.salaryId = s2.salaryPoint"
+ " left join team t2 on t2.id = s.teamId"
+ " ),"
+ " cte_timesheet_sum as ("
+ " Select p.code, sum((IFNULL(t.normalConsumed, 0) + IFNULL(t.otConsumed , 0)) * s2.hourlyRate) as sumManhourExpenditure"
+ " from timesheet t"
+ " left join project_task pt on pt.id = t.projectTaskId"
+ " left join project p ON p.id = pt.project_id"
+ " left join staff s on s.id = t.staffId"
+ " left join salary s2 on s.salaryId = s2.salaryPoint"
+ " group by p.code"
+ " ),"
+ " cte_invoice as ("
+ " select p.code, sum(i.issueAmount) as sumIssuedAmount , sum(i.paidAmount) as sumPaidAmount"
+ " from invoice i"
@@ -1893,10 +1912,11 @@ open class ReportService(
+ " select p.code, p.description, c.name as client, IFNULL(s2.name, \"N/A\") as subsidiary, concat(t.code, \" - \", t.name) as teamLead,"
+ " IFNULL(cte_ts.normalConsumed, 0) as normalConsumed, IFNULL(cte_ts.otConsumed, 0) as otConsumed, DATE_FORMAT(cte_ts.recordDate, '%Y-%m') as recordDate, "
+ " IFNULL(cte_ts.salaryPoint, 0) as salaryPoint, "
+ " IFNULL(cte_ts.hourlyRate, 0) as hourlyRate, IFNULL(cte_i.sumIssuedAmount, 0) as sumIssuedAmount, IFNULL(cte_i.sumPaidAmount, 0) as sumPaidAmount,"
+ " IFNULL(cte_ts.hourlyRate, 0) as hourlyRate, IFNULL(cte_i.sumIssuedAmount, 0) as sumIssuedAmount, IFNULL(cte_i.sumPaidAmount, 0) as sumPaidAmount, IFNULL(cte_tss.sumManhourExpenditure, 0) as sumManhourExpenditure,"
+ " s.name, s.staffId, g.code as gradeCode, g.name as gradeName, t2.code as teamCode, t2.name as teamName"
+ " from project p"
+ " left join cte_timesheet cte_ts on p.code = cte_ts.code"
+ " left join cte_timesheet_sum cte_tss on p.code = cte_tss.code"
+ " left join customer c on c.id = p.customerId"
+ " left join tsmsdb.team t on t.teamLead = p.teamLead"
+ " left join cte_invoice cte_i on cte_i.code = p.code"
@@ -1959,6 +1979,9 @@ open class ReportService(
if (info["code"] == item["code"] && "subsidiary" !in info) {
info["subsidiary"] = item.getValue("subsidiary")
}
if (info["manhourExpenditure"] != item.getValue("sumManhourExpenditure")) {
info["manhourExpenditure"] = item.getValue("sumManhourExpenditure")
}
if (info["description"] != item.getValue("description")) {
info["description"] = item.getValue("description")
}
@@ -2319,7 +2342,8 @@ open class ReportService(
}
val totalManhourECell = totalManhourERow.getCell(1) ?: totalManhourERow.createCell(1)
totalManhourECell.apply {
cellFormula = "SUM(${lastColumnIndex}${startRow}:${lastColumnIndex}${startRow + staffInfoList.size})"
// cellFormula = "SUM(${lastColumnIndex}${startRow}:${lastColumnIndex}${startRow + staffInfoList.size})"
setCellValue(info.getValue("manhourExpenditure") as Double)
cellStyle.dataFormat = accountingStyle
}
CellUtil.setCellStyleProperty(totalManhourETitleCell, "borderBottom", BorderStyle.THIN)


+ 5
- 1
src/main/java/com/ffii/tsms/modules/report/web/ReportController.kt Visa fil

@@ -34,6 +34,8 @@ import java.time.format.DateTimeFormatter
import com.ffii.tsms.modules.project.entity.Project
import com.ffii.tsms.modules.project.service.SubsidiaryService
import com.ffii.tsms.modules.report.web.model.*
import org.apache.commons.logging.Log
import org.apache.commons.logging.LogFactory
import org.springframework.data.domain.Example
import org.springframework.data.domain.ExampleMatcher

@@ -58,6 +60,7 @@ class ReportController(
private val subsidiaryRepository: SubsidiaryRepository
) {

private val logger: Log = LogFactory.getLog(javaClass)
@PostMapping("/fetchProjectsFinancialStatusReport")
@Throws(ServletRequestBindingException::class, IOException::class)
fun getFinancialStatusReport(@RequestBody @Valid request: FinancialStatusReportRequest): ResponseEntity<Resource> {
@@ -76,7 +79,8 @@ class ReportController(

val project = projectRepository.findById(request.projectId).orElseThrow()
val projectTasks = projectTaskRepository.findAllByProject(project)
val invoices = invoiceService.findAllByProjectAndPaidAmountIsNotNull(project)
// val invoices = invoiceService.findAllByProjectAndPaidAmountIsNotNull(project)
val invoices = invoiceRepository.findAllByProjectCodeAndPaidAmountIsNotNull(project.code!!)
val timesheets = timesheetRepository.findAllByProjectTaskIn(projectTasks)

val reportResult: ByteArray = excelReportService.generateProjectCashFlowReport(project, invoices, timesheets, request.dateType)


Binär
src/main/resources/templates/report/AR04_Cost and Expense Report v02.xlsx Visa fil


Binär
src/main/resources/templates/report/AR08_Monthly Work Hours Analysis Report.xlsx Visa fil


Laddar…
Avbryt
Spara