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

update financial year

add_swagger
MSI\derek 10 месяцев назад
Родитель
Сommit
85359415de
2 измененных файлов: 258 добавлений и 1 удалений
  1. +232
    -1
      src/main/java/com/ffii/tsms/modules/data/service/DashboardService.kt
  2. +26
    -0
      src/main/java/com/ffii/tsms/modules/data/web/DashboardController.kt

+ 232
- 1
src/main/java/com/ffii/tsms/modules/data/service/DashboardService.kt Просмотреть файл

@@ -36,6 +36,7 @@ import java.math.BigDecimal
import java.time.LocalDate
import java.time.format.DateTimeFormatter
import java.util.Optional
import kotlin.time.times

@Service
open class DashboardService(
@@ -3223,6 +3224,142 @@ open class DashboardService(

return outputStream.toByteArray()
}
open fun testing3(
projectId: Long,
startDate: LocalDate?,
endDate: LocalDate?,
) {
val project = projectRepository.findById(projectId).orElseThrow()
val timesheet = timesheetRepository.findAll()
val pe = projectExpenseRepository.findAllByProjectIdAndDeletedFalse(projectId)
val invoice = invoiceRepository.findAll()
}
open fun testing2 (
projectId: Long,
startDate: LocalDate?,
endDate: LocalDate?,
): DashboardData {
var manhourExpense = 0.0
var projectExpense = 0.0
var invoicedAmount = 0.0
var receivedAmount = 0.0

// val salaryEffective =
val project = projectRepository.findById(projectId).orElseThrow()
val timesheet = timesheetRepository.findAll()
val pe = projectExpenseRepository.findAllByProjectIdAndDeletedFalse(projectId)
val invoice = invoiceRepository.findAll()
val maxSize = maxOf(timesheet.size, pe.size, invoice.size)
var lIdx = 0
var rIdx = maxSize - 1
while (lIdx<=rIdx) {
// timesheet data
val currTimesheetL = timesheet.getOrNull(lIdx)
val currTimesheetR = timesheet.getOrNull(rIdx)
val otMultiplier = 1.0
val crossTeamMultiplier = 1.0
if (currTimesheetL == currTimesheetR && currTimesheetL != null) {
val se = salaryEffectiveService.getStaffSalaryEffective(currTimesheetL.staff!!.id!!, currTimesheetL.recordDate!!)
if (currTimesheetL.deleted == false
&& currTimesheetL.project?.id != null
&& CheckingUtils.checkTimePeriod(currTimesheetL.recordDate!!, startDate, endDate)) {
val normalCost = (currTimesheetL.normalConsumed ?: 0.0)
val otCost = (currTimesheetL.otConsumed ?: 0.0).times(otMultiplier)
manhourExpense += if (currTimesheetL.project!!.teamLead?.team!!.id != currTimesheetL.staff!!.team.id)
(normalCost+otCost).times(crossTeamMultiplier)
else normalCost+otCost
}
} else {
if (currTimesheetL != null && currTimesheetL.deleted == false
&& currTimesheetL.project?.id != null
&& CheckingUtils.checkTimePeriod(currTimesheetL.recordDate!!, startDate, endDate)) {
val se = salaryEffectiveService.getStaffSalaryEffective(currTimesheetL.staff!!.id!!, currTimesheetL.recordDate!!)
val normalCost = (currTimesheetL.normalConsumed ?: 0.0).times(se?.salary!!.hourlyRate.toDouble() ?: 0.0)
val otCost = (currTimesheetL.otConsumed ?: 0.0).times(otMultiplier)
manhourExpense += if (currTimesheetL.project!!.teamLead?.team!!.id != currTimesheetL.staff!!.team.id)
(normalCost+otCost).times(crossTeamMultiplier)
else normalCost+otCost
}
if (currTimesheetR != null && currTimesheetR.deleted == false
&& currTimesheetR.project?.id != null
&& CheckingUtils.checkTimePeriod(currTimesheetR.recordDate!!, startDate, endDate)) {
val se = salaryEffectiveService.getStaffSalaryEffective(currTimesheetR.staff!!.id!!, currTimesheetR.recordDate!!)
val normalCost = (currTimesheetR.normalConsumed ?: 0.0).times(se?.salary!!.hourlyRate.toDouble() ?: 0.0)
val otCost = (currTimesheetR.otConsumed ?: 0.0).times(otMultiplier).times(se?.salary!!.hourlyRate.toDouble() ?: 0.0)
manhourExpense += if (currTimesheetR.project!!.teamLead?.team!!.id != currTimesheetR.staff!!.team.id)
(normalCost+otCost).times(crossTeamMultiplier)
else normalCost+otCost
}
}
// project expense
val currProjectExpenseL = pe.getOrNull(lIdx)
val currProjectExpenseR = pe.getOrNull(rIdx)
if (currProjectExpenseL == currProjectExpenseR && currProjectExpenseL != null) {
if (currProjectExpenseL.deleted == false
&& currProjectExpenseL.project!!.id == projectId
&& CheckingUtils.checkTimePeriod(currProjectExpenseL.issueDate!!, startDate, endDate)) {
projectExpense += currProjectExpenseL.amount!!
}
} else {
if (currProjectExpenseL != null && currProjectExpenseL.deleted == false
&& currProjectExpenseL.project!!.id == projectId
&& CheckingUtils.checkTimePeriod(currProjectExpenseL.issueDate!!, startDate, endDate)) {
projectExpense += currProjectExpenseL.amount!!
}
if (currProjectExpenseR != null && currProjectExpenseR.deleted == false
&& currProjectExpenseR.project!!.id == projectId
&& CheckingUtils.checkTimePeriod(currProjectExpenseR.issueDate!!, startDate, endDate)) {
projectExpense += currProjectExpenseR.amount!!
}
}
// invoice data
val currInvoiceL = invoice.getOrNull(lIdx)
val currInvoiceR = invoice.getOrNull(rIdx)
if (currInvoiceL == currInvoiceR && currInvoiceL != null) {
if (currInvoiceL.deleted == false
&& currInvoiceL.projectCode == project.code
&& CheckingUtils.checkTimePeriod(currInvoiceL.invoiceDate!!, startDate, endDate)) {
invoicedAmount += currInvoiceL.issueAmount?.toDouble() ?: 0.0
receivedAmount += currInvoiceL.paidAmount?.toDouble() ?: 0.0
}
} else {
if (currInvoiceL != null
&& currInvoiceL.deleted == false
&& currInvoiceL.projectCode == project.code
&& CheckingUtils.checkTimePeriod(currInvoiceL.invoiceDate!!, startDate, endDate)) {
invoicedAmount += currInvoiceL.issueAmount?.toDouble() ?: 0.0
receivedAmount += currInvoiceL.paidAmount?.toDouble() ?: 0.0
}
if (currInvoiceR != null
&& currInvoiceR.deleted == false
&& currInvoiceR.projectCode == project.code
&& CheckingUtils.checkTimePeriod(currInvoiceR.invoiceDate!!, startDate, endDate)) {
invoicedAmount += currInvoiceR.issueAmount?.toDouble() ?: 0.0
receivedAmount += currInvoiceR.paidAmount?.toDouble() ?: 0.0
}
}

lIdx++
rIdx--
}
val nonInvoicedAmount = (project.expectedTotalFee?: 0.0) - invoicedAmount
val cumulativeExpenditure = manhourExpense + projectExpense
val output = DashboardData(
cumulativeExpenditure,
manhourExpense,
projectExpense,
invoicedAmount,
nonInvoicedAmount,
receivedAmount,
// if (invoicedAmount >= manhourExpense+projectExpense) "Positive" else "Negative",
// if (project.expectedTotalFee!! >= cumulativeExpenditure) "Positive" else "Negative",
if (cumulativeExpenditure > 0.0) invoicedAmount/cumulativeExpenditure else 0.0,
if (cumulativeExpenditure > 0.0) project.expectedTotalFee!!/cumulativeExpenditure else 0.0
)
return output
// println("invoicedAmount: $invoicedAmount")
// println("receivedAmount: $receivedAmount")
}

open fun testing (
projectId: Long,
@@ -3297,6 +3434,100 @@ open class DashboardService(
)
return output
}
open fun getFinancialSummaryByProjectSQL(args: Map<String, Any>): List<Map<String, Any>> {
// timesheet data
val sql = StringBuilder("with manhourExpense as ("
+ " with p_cte as ( "
+ " select "
+ " p.*, "
+ " s.teamId "
+ " from project p "
+ " left join staff s on s.id = p.teamLead "
+ " where p.deleted = false "
+ " ) "
+ " select "
+ " projectId, "
+ " CASE WHEN tl.teamId = p.teamId "
+ " THEN (sum(coalesce(t.normalConsumed, 0)) + sum(coalesce(t.otConsumed, 0)))*max(sal.hourlyRate) "
+ " ELSE ((sum(coalesce(t.normalConsumed, 0)) + sum(coalesce(t.otConsumed, 0)))*max(sal.hourlyRate)) * 1 " // cross team multiplier
+ " END AS manhourExpense "
+ " from ( "
+ " SELECT * "
+ " FROM timesheet t "
+ " where t.deleted = false "
+ (if (args.containsKey("startDate") && args.containsKey("endDate")) " and t.recordDate between :startDate AND :endDate "
else if (args.containsKey("endDate")) " and t.recordDate <= :endDate "
else "")
+ " and t.projectId is not null "
+ " ) t "
+ " left join p_cte p on p.id = t.projectId "
+ " left join team_log tl on tl.staffId = t.staffId and t.recordDate between tl.`from` AND tl.`to` "
+ " inner JOIN salary_effective se ON se.staffId = t.staffId and t.recordDate between se.startDate AND se.endDate "
+ " left join salary sal on sal.salaryPoint = se.salaryId "
+ " GROUP BY t.projectId, tl.teamId, p.teamId "
+ " ) "
// invoice data
+ " , invoice_data as ( "
+ " select "
+ " p.id as projectId, "
+ " sum(coalesce(i.issueAmount, 0)) as invoicedAmount, "
+ " sum(coalesce(i.paidAmount, 0)) as paidAmount "
+ " from invoice i "
+ " left join project p on p.code = i.projectCode "
+ " left join staff s on s.id = p.teamlead "
+ " where i.deleted = false "
+ (if (args.containsKey("startDate") && args.containsKey("endDate")) " and i.receiptDate between :startDate AND :endDate "
else if (args.containsKey("endDate")) " and i.receiptDate <= :endDate "
else "")
+ " group by p.id "
+ " ) "
// project_expense
+ " , project_expense as ( "
+ " select "
+ " pe.projectId, "
+ " sum(amount) as projectExpense "
+ " from project_expense pe "
+ " left join project p on p.id = pe.projectId "
+ " left join staff s on s.id = p.teamlead "
+ " where pe.deleted = false "
+ (if (args.containsKey("startDate") && args.containsKey("endDate")) " and pe.issueDate between :startDate AND :endDate "
else if (args.containsKey("endDate")) " and pe.issueDate <= :endDate "
else "")
+ " group by pe.projectId "
+ " ) "
+ " select "
+ " * "
+ " from ( "
+ " select "
+ " p.id, "
+ " p.name as projectName, "
+ " p.code as projectCode, "
+ " s.teamId, "
+ " t.name as team, "
+ " c.id as custId, "
+ " c.name as customerName, "
+ " c.code as customerCode, "
+ " su.name as subsidiary, "
+ " p.expectedTotalFee as totalFee, "
+ " (p.expectedTotalFee - ifnull(p.subContractFee, 0)) * 0.8 as totalBudget, "
+ " coalesce(me.manhourExpense, 0) as manhourExpense, "
+ " coalesce(id.invoicedAmount, 0) as invoicedAmount, "
+ " coalesce(id.paidAmount, 0) as paidAmount, "
+ " coalesce(pe.projectExpense, 0) as projectExpense "
+ " from project p "
+ " inner join staff s on s.id = p.teamlead "
+ " left join team t on s.teamId = t.id "
+ " left join customer c on c.id = p.customerId "
+ " left join subsidiary su on su.id = p.customerSubsidiaryId "
+ " left join manhourExpense me on me.projectId = p.id "
+ " left join invoice_data id on id.projectId = p.id "
+ " left join project_expense pe on pe.projectId = p.id "
+ " where p.status = 'On-going' "
+ (if (args.containsKey("teamId")) "where s.teamId = :teamId" else "")
+ " order by p.id "
+ " ) result ")
return jdbcDao.queryForList(sql.toString(), args)
}

open fun getProjectDashboardDataByProjectId(
projectId: Long,
@@ -3333,7 +3564,7 @@ open class DashboardService(
val projects = projectRepository.findAll()
for (curr in projects) {
if (curr.deleted == false && curr.teamLead?.team?.id == teamId && curr.status == "On-going") {
val data = testing(curr.id!!, startDate, endDate)
val data = testing2(curr.id!!, startDate, endDate)
val item = mapOf<String, Any>(
"id" to curr.id!!,
"custId" to if (curr.customer != null ) curr.customer!!.id else -1,


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

@@ -482,9 +482,34 @@ class DashboardController(
println("end...: ${LocalDateTime.now()}")
return output
}
@GetMapping("/getFinancialSummary-final")
fun getFinancialSummaryBySql(@Valid request: HttpServletRequest): List<Map<String, Any>> {
println("")
println("start: ${LocalDateTime.now().minute}:${LocalDateTime.now().second}")
val startDate = if (request.getParameter("startDate") != null) LocalDate.parse(request.getParameter("startDate")) else null
val endDate = if (request.getParameter("endDate") != null) LocalDate.parse(request.getParameter("endDate")) else null
val teamId = if (request.getParameter("teamId") != null) request.getParameter("teamId") else null
val args = mutableMapOf<String, Any>()
if (startDate != null) args["startDate"] = startDate
if (endDate != null) args["endDate"] = endDate
if (teamId != null) args["teamId"] = teamId
val output = dashboardService.getFinancialSummaryByProjectSQL(args)
println("end: ${LocalDateTime.now().minute}:${LocalDateTime.now().second}")
return output
}
// @GetMapping("/fromScratch")
// fun fromScratch(@Valid request: HttpServletRequest): List<Map<String, Any>> {
// val startDate = if (request.getParameter("startDate") != null) LocalDate.parse(request.getParameter("startDate")) else null
// val endDate = LocalDate.parse(request.getParameter("endDate"))
// val targetTeam = request.getParameter("teamId") ?: null
// // loop all
//
// }

@GetMapping("/getFinancialSummary")
fun getFinancialSummary(@Valid request: HttpServletRequest): List<Map<String, Any>> {
println("")
println("start: ${LocalDateTime.now().minute}:${LocalDateTime.now().second}")
val output = mutableListOf<Map<String, Any>>()
val startDate = if (request.getParameter("startDate") != null) LocalDate.parse(request.getParameter("startDate")) else null
val endDate = LocalDate.parse(request.getParameter("endDate"))
@@ -500,6 +525,7 @@ class DashboardController(
for (id in teamIds) {
output.add(dashboardService.fetchFinancialSummary(startDate, endDate, id))
}
println("start: ${LocalDateTime.now().minute}:${LocalDateTime.now().second}")
return output
}



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