Преглед изворни кода

Add Edit Invoice Detail

tags/Baseline_30082024_BACKEND_UAT
MSI\2Fi пре 1 година
родитељ
комит
4eaa6e98b0
6 измењених фајлова са 166 додато и 59 уклоњено
  1. +0
    -1
      src/main/java/com/ffii/tsms/modules/project/entity/Invoice.kt
  2. +127
    -58
      src/main/java/com/ffii/tsms/modules/project/service/InvoiceService.kt
  3. +7
    -0
      src/main/java/com/ffii/tsms/modules/project/web/InvoiceController.kt
  4. +13
    -0
      src/main/java/com/ffii/tsms/modules/project/web/models/EditInvoiceRequest.kt
  5. +15
    -0
      src/main/java/com/ffii/tsms/modules/project/web/models/EditInvoiceResponse.kt
  6. +4
    -0
      src/main/resources/db/changelog/changes/20240718_01_jasonT/01_alter_invoice_table_dueDate_nallable.sql

+ 0
- 1
src/main/java/com/ffii/tsms/modules/project/entity/Invoice.kt Прегледај датотеку

@@ -27,7 +27,6 @@ open class Invoice : BaseEntity<Long>(){
@Column(name = "invoiceDate")
open var invoiceDate: LocalDate? = null

@NotNull
@Column(name = "dueDate")
open var dueDate: LocalDate? = null



+ 127
- 58
src/main/java/com/ffii/tsms/modules/project/service/InvoiceService.kt Прегледај датотеку

@@ -9,6 +9,8 @@ import com.ffii.tsms.modules.project.entity.projections.InvoiceInfo

import com.ffii.tsms.modules.project.entity.projections.InvoicePDFReq
import com.ffii.tsms.modules.project.entity.projections.ProjectSearchInfo
import com.ffii.tsms.modules.project.web.models.EditInvoiceRequest
import com.ffii.tsms.modules.project.web.models.EditInvoiceResponse
import com.ffii.tsms.modules.project.web.models.InvoiceResponse
import net.sf.jasperreports.engine.JasperCompileManager
import net.sf.jasperreports.engine.JasperReport
@@ -22,6 +24,9 @@ import java.io.InputStream
import java.math.BigDecimal
import java.time.LocalDate
import java.time.ZoneId
import java.time.format.DateTimeFormatter
import java.util.Optional
import kotlin.math.min


@Service
@@ -357,7 +362,7 @@ open class InvoiceService(
// For checking mandatory field in each row
val emptyRowList: MutableList<Int> = mutableListOf()
// Beria cannot provide Payment Milestone when importing the invoice, so it cannot be checked and import to DB
val mandatoryColumns = listOf(0,1,10,11,12) // Mandatory Field in column 0,1,10,11,12
val mandatoryColumns = listOf(0,1,2,3) // Mandatory Field in column 0,1,10,11,12

if (workbook == null) {
return InvoiceResponse(false, "No Excel import", newProjectCodes, emptyRowList, invoicesResult, ArrayList(), ArrayList()) // if workbook is null
@@ -412,17 +417,17 @@ open class InvoiceService(
val invoice = Invoice().apply {
invoiceNo = ExcelUtils.getCell(sheet, i, 0).toString()
projectCode = ExcelUtils.getCell(sheet, i, 1).stringCellValue
projectName = ExcelUtils.getCell(sheet, i, 2).stringCellValue
team = ExcelUtils.getCell(sheet, i, 3).stringCellValue
stage = ExcelUtils.getCell(sheet, i, 4).numericCellValue.toString()
paymentMilestone = ExcelUtils.getCell(sheet, i, 5).stringCellValue
paymentMilestoneDate = ExcelUtils.getCell(sheet, i, 6).dateCellValue?.toInstant()?.atZone(ZoneId.systemDefault())?.toLocalDate()
client = ExcelUtils.getCell(sheet, i, 7).stringCellValue
address = ExcelUtils.getCell(sheet, i, 8).stringCellValue
attention = ExcelUtils.getCell(sheet, i, 9).stringCellValue
invoiceDate = ExcelUtils.getCell(sheet, i, 10).dateCellValue.toInstant().atZone(ZoneId.systemDefault()).toLocalDate()
dueDate = ExcelUtils.getCell(sheet, i, 11).dateCellValue.toInstant().atZone(ZoneId.systemDefault()).toLocalDate()
issueAmount = ExcelUtils.getCell(sheet, i, 12).numericCellValue.toBigDecimal()
// projectName = ExcelUtils.getCell(sheet, i, 2).stringCellValue
// team = ExcelUtils.getCell(sheet, i, 3).stringCellValue
// stage = ExcelUtils.getCell(sheet, i, 4).numericCellValue.toString()
// paymentMilestone = ExcelUtils.getCell(sheet, i, 5).stringCellValue
// paymentMilestoneDate = ExcelUtils.getCell(sheet, i, 6).dateCellValue?.toInstant()?.atZone(ZoneId.systemDefault())?.toLocalDate()
// client = ExcelUtils.getCell(sheet, i, 7).stringCellValue
// address = ExcelUtils.getCell(sheet, i, 8).stringCellValue
// attention = ExcelUtils.getCell(sheet, i, 9).stringCellValue
invoiceDate = ExcelUtils.getCell(sheet, i, 2).dateCellValue.toInstant().atZone(ZoneId.systemDefault()).toLocalDate()
// dueDate = ExcelUtils.getCell(sheet, i, 11).dateCellValue.toInstant().atZone(ZoneId.systemDefault()).toLocalDate()
issueAmount = ExcelUtils.getCell(sheet, i, 3).numericCellValue.toBigDecimal()
// Beria cannot provide Payment Milestone when importing the invoice, so it cannot be checked and import to DB
// this.milestonePayment = milestonePayment
}
@@ -443,7 +448,7 @@ open class InvoiceService(

// For checking mandatory field in each row
val emptyRowList: MutableList<Int> = mutableListOf()
val mandatoryColumns = listOf(0,1,4,5) // Mandatory Field in column 0,1,4,5
val mandatoryColumns = listOf(0,1,2,3) // Mandatory Field in column 0,1,4,5

if (workbook == null) {
return InvoiceResponse(false, "No Excel import", newProjectCodes, emptyRowList, invoicesResult, ArrayList(), ArrayList()) // if workbook is null
@@ -502,8 +507,8 @@ open class InvoiceService(

for (i in 2..sheet.lastRowNum){
val invoice = getInvoiceByInvoiceNo(ExcelUtils.getCell(sheet, i, 0).toString())
invoice.paidAmount = ExcelUtils.getCell(sheet, i, 5).numericCellValue.toBigDecimal()
invoice.receiptDate = ExcelUtils.getCell(sheet, i, 4).dateCellValue.toInstant().atZone(ZoneId.systemDefault()).toLocalDate()
invoice.paidAmount = ExcelUtils.getCell(sheet, i, 3).numericCellValue.toBigDecimal()
invoice.receiptDate = ExcelUtils.getCell(sheet, i, 2).dateCellValue.toInstant().atZone(ZoneId.systemDefault()).toLocalDate()
saveAndFlush(invoice)
}

@@ -520,52 +525,77 @@ open class InvoiceService(
val importInvoices: MutableList<Map<String, Any>> = mutableListOf();

val sheet: Sheet = workbook.getSheetAt(1)
println(sheet.lastRowNum)
for(i in 3 until sheet.lastRowNum){
val issueYear = ExcelUtils.getCell(sheet, i, convertAlphaToNumber("B")).numericCellValue
val issueMonth = ExcelUtils.getCell(sheet, i, convertAlphaToNumber("C")).numericCellValue
val issueDay = ExcelUtils.getCell(sheet, i, convertAlphaToNumber("D")).numericCellValue
val adjustedYear = if (issueYear < 100) 2000 + issueYear else issueYear
val issueDate = convertToLocalDate(adjustedYear.toInt(), issueMonth.toInt(), issueDay.toInt())

val projectPrefix = getCellValue(sheet, i, convertAlphaToNumber("E") )
val projectNo = getCellValue(sheet, i, convertAlphaToNumber("F") )
val projectCode = "${projectPrefix}-${projectNo}"
println("${i}: ${projectCode}")

val invoicePrefix1 = getCellValueWithBracket(sheet, i, convertAlphaToNumber("G") )
val invoicePrefix2 = getCellValueWithBracket(sheet, i, convertAlphaToNumber("H") )
val invoicePrefix3 = getCellValue(sheet, i, convertAlphaToNumber("I") )
val invoicePrefix4 = getCellValue(sheet, i, convertAlphaToNumber("J") )
// Put the cell into list, if cell is empty not join with "-"
val invoiceNo = listOf(projectCode, invoicePrefix1, invoicePrefix2, invoicePrefix3, invoicePrefix4)
.filter { it.isNotEmpty() }
.joinToString("-")

val issuedAmount = ExcelUtils.getCell(sheet, i, convertAlphaToNumber("M")).numericCellValue
val canceledAmount = ExcelUtils.getCell(sheet, i, convertAlphaToNumber("N")).numericCellValue
val settleYear = ExcelUtils.getCell(sheet, i, convertAlphaToNumber("Q")).numericCellValue
val settleMonth = ExcelUtils.getCell(sheet, i, convertAlphaToNumber("R")).numericCellValue
val settleDay = ExcelUtils.getCell(sheet, i, convertAlphaToNumber("S")).numericCellValue
val adjustedSettleYear = if (settleYear < 100) 2000 + settleYear else settleYear
val settleDate = convertToLocalDate(adjustedSettleYear.toInt(), settleMonth.toInt(), settleDay.toInt())
val receivedAmount = ExcelUtils.getCell(sheet, i, convertAlphaToNumber("T")).numericCellValue

val importInvoice: Map<String, Any> = mapOf(
"invoiceNo" to invoiceNo,
"projectCode" to projectCode,
"issuedAmount" to issuedAmount,
"canceledAmount" to canceledAmount,
"invoiceDate" to issueDate,
"receiptDate" to settleDate,
"receivedAmount" to receivedAmount,
)
importInvoices.add(importInvoice)
val lastRow = sheet.lastRowNum
val physicalRows = sheet.physicalNumberOfRows
println(lastRow)
println(physicalRows)

for(i in 3 until minOf(lastRow, physicalRows)){
val row = sheet.getRow(i)
if(row != null){
val issueYear = ExcelUtils.getCell(sheet, i, convertAlphaToNumber("B")).numericCellValue
val issueMonth = ExcelUtils.getCell(sheet, i, convertAlphaToNumber("C")).numericCellValue
val issueDay = ExcelUtils.getCell(sheet, i, convertAlphaToNumber("D")).numericCellValue
val adjustedYear = if (issueYear < 100) 2000 + issueYear else issueYear
val issueDate = convertToLocalDate(adjustedYear.toInt(), issueMonth.toInt(), issueDay.toInt())

val projectPrefix = getCellValue(sheet, i, convertAlphaToNumber("E") ) // got error why
val projectNo = getCellValue(sheet, i, convertAlphaToNumber("F") )
val projectCode = "${projectPrefix}-${projectNo}"
println("${i}: ${projectCode}")

val invoicePrefix1 = getCellValueWithBracket(sheet, i, convertAlphaToNumber("G") )
val invoicePrefix2 = getCellValueWithBracket(sheet, i, convertAlphaToNumber("H") )
val invoicePrefix3 = getCellValue(sheet, i, convertAlphaToNumber("I") )
val invoicePrefix4 = getCellValue(sheet, i, convertAlphaToNumber("J") )
// Put the cell into list, if cell is empty not join with "-"
val invoiceNo = listOf(projectCode, invoicePrefix1, invoicePrefix2, invoicePrefix3, invoicePrefix4)
.filter { it.isNotEmpty() }
.joinToString("-")

val issuedAmount = ExcelUtils.getCell(sheet, i, convertAlphaToNumber("M")).numericCellValue
val canceledAmount = ExcelUtils.getCell(sheet, i, convertAlphaToNumber("N")).numericCellValue
val settleYear = ExcelUtils.getCell(sheet, i, convertAlphaToNumber("Q")).numericCellValue
val settleMonth = ExcelUtils.getCell(sheet, i, convertAlphaToNumber("R")).numericCellValue
val settleDay = ExcelUtils.getCell(sheet, i, convertAlphaToNumber("S")).numericCellValue
val adjustedSettleYear = if (settleYear < 100) 2000 + settleYear else settleYear
val settleDate = convertToLocalDate(adjustedSettleYear.toInt(), settleMonth.toInt(), settleDay.toInt())
val receivedAmount = ExcelUtils.getCell(sheet, i, convertAlphaToNumber("T")).numericCellValue

val importInvoice: Map<String, Any> = mapOf(
"invoiceNo" to invoiceNo,
"projectCode" to projectCode,
"issuedAmount" to issuedAmount.toBigDecimal().setScale(2),
"canceledAmount" to canceledAmount.toBigDecimal().setScale(2),
"invoiceDate" to issueDate,
"receiptDate" to settleDate,
"receivedAmount" to receivedAmount.toBigDecimal().setScale(2),
)
importInvoices.add(importInvoice)
}
}

println("invoiceRecords: $invoiceRecords")
// println("invoiceRecords: $invoiceRecords")
println("------------------------------------- intersect -------------------------------------")
val (intersect, notIntersect) = importInvoices.partition { item ->
println("item---------------- $item")
invoiceRecords.any { invoice ->
println("Start any")
println("invoice.invoiceDate-------------- ${invoice.invoiceDate}")
println("item[\"invoiceDate\"]-------------- ${item["invoiceDate"]}")
println(invoice.invoiceDate == item["invoiceDate"])
println("----")
println("invoice.receiptDate-------------- ${invoice.receiptDate}")
println("item[\"receiptDate\"]-------------- ${item["receiptDate"]}")
print(invoice.receiptDate == item["receiptDate"])
println("----")
// println("invoice.receivedAmount-------------- ${invoice.receivedAmount}")
// println("item[\"receivedAmount\"]-------------- ${item["receivedAmount"]}")
// println(invoice.receivedAmount == item["receivedAmount"])
// println("----")
// println("invoice.issuedAmount-------------- ${invoice.issuedAmount}")
// println("item[\"issuedAmount\"]-------------- ${item["issuedAmount"]}")
// println(invoice.issuedAmount == item["issuedAmount"])
invoice.invoiceNo == item["invoiceNo"] &&
invoice.invoiceDate == item["invoiceDate"] &&
invoice.receiptDate == item["receiptDate"] &&
@@ -597,7 +627,7 @@ open class InvoiceService(

fun getCellValueWithBracket(sheet: Sheet, rowIndex: Int, columnIndex: Int): String {
val row = sheet.getRow(rowIndex)
val cell = row.getCell(columnIndex)
val cell = row.getCell(columnIndex) ?: return ""

return when (cell.cellType) {
CellType.NUMERIC -> "(${cell.numericCellValue.toInt()})"
@@ -651,4 +681,43 @@ open class InvoiceService(
return result
}

open fun updateInvoiceDetail(editInvoiceRequest :EditInvoiceRequest): EditInvoiceResponse {
val invoice = repository.findById(editInvoiceRequest.id)
val formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd")
println("${editInvoiceRequest.issuedDate}, ${editInvoiceRequest.receiptDate}")
if (invoice.isPresent){
val updateInvocie = invoice.get().apply {
invoiceNo = editInvoiceRequest.invoiceNo
issueAmount = editInvoiceRequest.issuedAmount
paidAmount = editInvoiceRequest.receivedAmount
invoiceDate = LocalDate.parse(editInvoiceRequest.issuedDate, formatter)
receiptDate = LocalDate.parse(editInvoiceRequest.receiptDate, formatter)
}.also { saveAndFlush(it) }

return updateInvocie.let {
EditInvoiceResponse(
id = it.id,
invoiceNo = it.invoiceNo,
issuedAmount = it.issueAmount,
issuedDate = it.invoiceDate,
receiptDate = it.receiptDate,
receivedAmount = it.paidAmount,
message = "success",
error = null
)
}
}else{
return EditInvoiceResponse(
id = null,
invoiceNo = null,
issuedAmount = null,
issuedDate = null,
receiptDate = null,
receivedAmount = null,
message = "fail",
error = "invoice not found"
)
}
}

}

+ 7
- 0
src/main/java/com/ffii/tsms/modules/project/web/InvoiceController.kt Прегледај датотеку

@@ -7,6 +7,8 @@ import com.ffii.tsms.modules.project.entity.projections.InvoicePDFReq
import com.ffii.tsms.modules.project.entity.projections.InvoiceSearchInfo
import com.ffii.tsms.modules.project.service.InvoiceService
import com.ffii.tsms.modules.project.service.ProjectsService
import com.ffii.tsms.modules.project.web.models.EditInvoiceRequest
import com.ffii.tsms.modules.project.web.models.EditInvoiceResponse
import jakarta.servlet.http.HttpServletRequest
import jakarta.servlet.http.HttpServletResponse
import net.sf.jasperreports.engine.JasperExportManager
@@ -138,4 +140,9 @@ class InvoiceController(
// println("--------- OK -------------")
return ResponseEntity.ok(invoiceService.importInvoices(workbook))
}

@PostMapping("/update")
fun updateInvoiceDetail(@RequestBody req: EditInvoiceRequest): EditInvoiceResponse {
return invoiceService.updateInvoiceDetail(req)
}
}

+ 13
- 0
src/main/java/com/ffii/tsms/modules/project/web/models/EditInvoiceRequest.kt Прегледај датотеку

@@ -0,0 +1,13 @@
package com.ffii.tsms.modules.project.web.models

import java.math.BigDecimal
import java.time.LocalDate

data class EditInvoiceRequest(
val id: Long,
val invoiceNo: String,
val issuedAmount: BigDecimal,
val issuedDate: String,
val receiptDate: String,
val receivedAmount: BigDecimal
)

+ 15
- 0
src/main/java/com/ffii/tsms/modules/project/web/models/EditInvoiceResponse.kt Прегледај датотеку

@@ -0,0 +1,15 @@
package com.ffii.tsms.modules.project.web.models

import java.math.BigDecimal
import java.time.LocalDate

data class EditInvoiceResponse (
val id: Long?,
val invoiceNo: String?,
val issuedAmount: BigDecimal?,
val issuedDate: LocalDate?,
val receiptDate: LocalDate?,
val receivedAmount: BigDecimal?,
val message: String?,
val error: String?
)

+ 4
- 0
src/main/resources/db/changelog/changes/20240718_01_jasonT/01_alter_invoice_table_dueDate_nallable.sql Прегледај датотеку

@@ -0,0 +1,4 @@
-- liquibase formatted sql
-- changeset jasonT:invoice, to align with latest Beria import issued invoice template

ALTER TABLE tsmsdb.invoice MODIFY COLUMN dueDate date NULL;

Loading…
Откажи
Сачувај