From 57eae66d03c28df1cb23e453d7ce394958a403c9 Mon Sep 17 00:00:00 2001 From: "MSI\\2Fi" Date: Fri, 10 May 2024 18:10:43 +0800 Subject: [PATCH] Receievd Inovice --- .../tsms/modules/project/entity/Invoice.kt | 2 +- .../project/entity/InvoiceRepository.kt | 2 + .../project/entity/projections/InvoiceInfo.kt | 5 + .../modules/project/service/InvoiceService.kt | 192 +++++++++++++++--- .../modules/project/web/InvoiceController.kt | 5 + .../project/web/models/InvoiceResponse.kt | 2 + .../modules/report/service/ReportService.kt | 4 +- 7 files changed, 181 insertions(+), 31 deletions(-) diff --git a/src/main/java/com/ffii/tsms/modules/project/entity/Invoice.kt b/src/main/java/com/ffii/tsms/modules/project/entity/Invoice.kt index 86a541a..3adc636 100644 --- a/src/main/java/com/ffii/tsms/modules/project/entity/Invoice.kt +++ b/src/main/java/com/ffii/tsms/modules/project/entity/Invoice.kt @@ -38,7 +38,7 @@ open class Invoice : BaseEntity(){ open var unpaidAmount: Double? = null @Column(name = "paidAmount") - open var paidAmount: Double? = null + open var paidAmount: BigDecimal? = null @Column(name = "projectCode") open var projectCode: String? = null diff --git a/src/main/java/com/ffii/tsms/modules/project/entity/InvoiceRepository.kt b/src/main/java/com/ffii/tsms/modules/project/entity/InvoiceRepository.kt index e30b641..cdedfc4 100644 --- a/src/main/java/com/ffii/tsms/modules/project/entity/InvoiceRepository.kt +++ b/src/main/java/com/ffii/tsms/modules/project/entity/InvoiceRepository.kt @@ -9,5 +9,7 @@ interface InvoiceRepository : AbstractRepository { fun findInvoiceInfoBy(): List + fun findInvoiceInfoByPaidAmountIsNotNull(): List + fun findByInvoiceNo(invoiceNo: String): Invoice } \ No newline at end of file diff --git a/src/main/java/com/ffii/tsms/modules/project/entity/projections/InvoiceInfo.kt b/src/main/java/com/ffii/tsms/modules/project/entity/projections/InvoiceInfo.kt index 1965541..5c76060 100644 --- a/src/main/java/com/ffii/tsms/modules/project/entity/projections/InvoiceInfo.kt +++ b/src/main/java/com/ffii/tsms/modules/project/entity/projections/InvoiceInfo.kt @@ -36,6 +36,11 @@ interface InvoiceInfo { val dueDate: LocalDate? + val receiptDate: LocalDate? + + @get:Value("#{target.paidAmount}") + val receivedAmount: BigDecimal? + @get:Value("#{target.issueAmount}") val issuedAmount: BigDecimal? diff --git a/src/main/java/com/ffii/tsms/modules/project/service/InvoiceService.kt b/src/main/java/com/ffii/tsms/modules/project/service/InvoiceService.kt index 8670554..c2c60c8 100644 --- a/src/main/java/com/ffii/tsms/modules/project/service/InvoiceService.kt +++ b/src/main/java/com/ffii/tsms/modules/project/service/InvoiceService.kt @@ -17,6 +17,7 @@ import org.apache.poi.ss.usermodel.CellType import org.apache.poi.ss.usermodel.Sheet import org.apache.poi.ss.usermodel.Workbook import org.springframework.core.io.ClassPathResource +import org.springframework.jdbc.core.namedparam.MapSqlParameterSource import org.springframework.stereotype.Service import org.springframework.transaction.annotation.Transactional import java.io.InputStream @@ -93,6 +94,20 @@ open class InvoiceService( return jdbcDao.queryForList(sql.toString(), args) } + open fun getMilestonePaymentWithProjectCode(code: List): List> { + val sql = StringBuilder("select " + + " p.code, mp.* " + + " from milestone_payment mp " + + " left join milestone m on mp.milestoneId = m.id " + + " left join project p on p.id = m.projectId " + + " where p.deleted = false " + + " and p.code in (:code) " + ) + val args = mapOf("code" to code) + + return jdbcDao.queryForList(sql.toString(), args) + } + open fun getInvoiceByInvoiceNo(invoiceNo: String): Invoice { return invoiceRepository.findByInvoiceNo(invoiceNo) } @@ -159,26 +174,100 @@ open class InvoiceService( } /** + * To Check the invoice no with DB Records * return the List of existing invoice no + * @param checkDuplicate true, return duplicate Invoice No */ - open fun checkInvocieNo( + open fun checkInvoiceNo( invoiceNo: String, invoices: List, invoicesResult: MutableList, checkDuplicate: Boolean ): List{ val existingInvoiceNos: List - existingInvoiceNos = if(checkDuplicate){ - invoices.filter { it.invoiceNo == invoiceNo }.map { it.invoiceNo } + existingInvoiceNos = invoices.filter { it.invoiceNo == invoiceNo }.map { it.invoiceNo } + + if (checkDuplicate){ + if (existingInvoiceNos.isNotEmpty()) { + invoicesResult.add(invoiceNo) + } }else{ - invoices.filter { it.invoiceNo != invoiceNo }.map { it.invoiceNo } + if (existingInvoiceNos.isEmpty()) { + invoicesResult.add(invoiceNo) + } } - if (existingInvoiceNos.isNotEmpty()) { - invoicesResult.add(invoiceNo) + return invoicesResult + } + + open fun checkDuplicateItemInImportedInvoice( + sheet: Sheet, + startingRow: Int, + columnIndex: Int + ): List { + val uniqueValues = HashSet() + val duplicateValues = HashSet() + + for (i in startingRow..sheet.lastRowNum) { + val row = sheet.getRow(i) + val cell = row?.getCell(columnIndex) + if (cell != null && cell.cellType == CellType.STRING) { + val cellValue = cell.stringCellValue + if (uniqueValues.contains(cellValue)) { + duplicateValues.add(cellValue) + } else { + uniqueValues.add(cellValue) + } + } } - return invoicesResult + return duplicateValues.toList() + } + + /** + * @return true when cellValue Object exist in DB + */ + fun checkStringExists(list: List>, cellValue: Map): Boolean { + println("LIST-------------: $list") + println("CELL VALUE-------------: $cellValue") + return list.contains(cellValue) + } + open fun checkMilestonePayment( + sheet: Sheet, + startingRow: Int, + columnIndex: Int, + invoiceColumnIndex: Int, + projectCodeColumnIndex: Int, + paymentMilestoneWithCode: List> + ): List> { + val nonExistMilestone: MutableList> = mutableListOf() + + for (i in startingRow..sheet.lastRowNum) { + val row = sheet.getRow(i) + val milestonePaymentCell = row?.getCell(columnIndex) + val invoiceNoCell = row?.getCell(invoiceColumnIndex) + val projectCodeCell = row?.getCell(projectCodeColumnIndex) + if (milestonePaymentCell != null && milestonePaymentCell.cellType == CellType.STRING && + invoiceNoCell != null && invoiceNoCell.cellType == CellType.STRING && + projectCodeCell != null && projectCodeCell.cellType == CellType.STRING) + { + val milestonePaymentCellValue = milestonePaymentCell.stringCellValue + val invoiceNoCellValue = invoiceNoCell.stringCellValue + val projectCodeCellValue = projectCodeCell.stringCellValue + + val cellValue = mapOf("code" to projectCodeCellValue, "description" to milestonePaymentCellValue) + + if(!checkStringExists(paymentMilestoneWithCode, cellValue)) { + if(!nonExistMilestone.contains(mapOf("paymentMilestone" to milestonePaymentCellValue, "invoiceNo" to invoiceNoCellValue))){ + nonExistMilestone.add(mapOf("paymentMilestone" to milestonePaymentCellValue, "invoiceNo" to invoiceNoCellValue)) + } + } + println("nonExistMilestone $nonExistMilestone") + } + + } + + return nonExistMilestone.toList() } open fun checkMandatoryField( @@ -192,13 +281,13 @@ open class InvoiceService( // (CellType.NUMERIC, CellType.STRING, CellType.BOOLEAN, CellType.ERROR) when(ExcelUtils.getCell(sheet, row, mandatoryColumns[i]).cellType){ CellType.NUMERIC -> { - println("NUMERIC" + ExcelUtils.getCell(sheet, row, mandatoryColumns[i]).numericCellValue) +// println("NUMERIC" + ExcelUtils.getCell(sheet, row, mandatoryColumns[i]).numericCellValue) if (ExcelUtils.getCell(sheet, row, mandatoryColumns[i]).numericCellValue.isNaN()){ emptyRowList.add(row) } } CellType.STRING -> { - println("STRING" + ExcelUtils.getCell(sheet, row, mandatoryColumns[i]).stringCellValue) +// println("STRING" + ExcelUtils.getCell(sheet, row, mandatoryColumns[i]).stringCellValue) if(ExcelUtils.getCell(sheet, row, mandatoryColumns[i]).stringCellValue.isBlank()){ emptyRowList.add(row) } @@ -218,6 +307,10 @@ open class InvoiceService( return invoiceRepository.findInvoiceInfoBy() } + open fun allInvoicePaid(): List{ + return invoiceRepository.findInvoiceInfoByPaidAmountIsNotNull() + } + @Transactional(rollbackFor = [Exception::class]) open fun importIssueInvoice(workbook: Workbook?): InvoiceResponse { @@ -226,39 +319,57 @@ open class InvoiceService( // For checking existence of projecrt code val newProjectCodes: MutableList = mutableListOf() + val projectsCodes: MutableList = mutableListOf() // For checking mandatory field in each row val emptyRowList: MutableList = mutableListOf() val mandatoryColumns = listOf(0,1,4,5,10,11,12) // Mandatory Field in column 0,1,4,5,10,11,12 if (workbook == null) { - return InvoiceResponse(false, "No Excel import", newProjectCodes, emptyRowList, invoicesResult) // if workbook is null + return InvoiceResponse(false, "No Excel import", newProjectCodes, emptyRowList, invoicesResult, ArrayList(), ArrayList()) // if workbook is null } val sheet: Sheet = workbook.getSheetAt(0) - val sheetValues: MutableList> = ArrayList() +// val sheetValues: MutableList> = ArrayList() // Get All invoices and Porjects from DB val invoices = allInvoice() val projects = projectService.allProjects() + val duplicateItemsInInvoice = checkDuplicateItemInImportedInvoice(sheet,2,0) + + // Check the import invoice with the data in DB for (i in 2..sheet.lastRowNum){ val sheetInvoice = ExcelUtils.getCell(sheet, i, 0).stringCellValue val sheetProjectCode = ExcelUtils.getCell(sheet, i, 1).stringCellValue - checkInvocieNo(sheetInvoice, invoices, invoicesResult, true) + checkInvoiceNo(sheetInvoice, invoices, invoicesResult, true) checkProjectCode(sheetProjectCode, projects, newProjectCodes) checkMandatoryField(mandatoryColumns, sheet, i, emptyRowList, 1) - println("For: $invoicesResult") - println("For: $newProjectCodes") +// println("For: $invoicesResult") +// println("For: $newProjectCodes") + if(!projectsCodes.contains(ExcelUtils.getCell(sheet, i, 1).stringCellValue)){ + projectsCodes.add(ExcelUtils.getCell(sheet, i, 1).stringCellValue) + } + } + + if (newProjectCodes.size == 0){ + val milestonepaymentWithCode = getMilestonePaymentWithProjectCode(projectsCodes) +// println("newProjectCodes == 0") +// println(checkMilestonePayment(sheet, 2, 5, 0, 1, milestonepaymentWithCode)) + val paymenMilestones = checkMilestonePayment(sheet, 2, 5, 0, 1, milestonepaymentWithCode) + if (paymenMilestones.isNotEmpty()){ + return InvoiceResponse(false, "Imported Invoice's format is incorrect", newProjectCodes, emptyRowList, invoicesResult, duplicateItemsInInvoice, paymenMilestones) + } } if (invoicesResult.size >= 1 || newProjectCodes.size >= 1 || - emptyRowList.size >= 1 + emptyRowList.size >= 1 || + duplicateItemsInInvoice.isNotEmpty() ){ println("invoicesResult") println(invoicesResult) - return InvoiceResponse(false, "Imported Invoice's format is incorrect", newProjectCodes, emptyRowList, invoicesResult) + return InvoiceResponse(false, "Imported Invoice's format is incorrect", newProjectCodes, emptyRowList, invoicesResult, duplicateItemsInInvoice, ArrayList()) } for (i in 2..sheet.lastRowNum){ @@ -280,7 +391,7 @@ open class InvoiceService( saveAndFlush(invoice) } - return InvoiceResponse(true, "OK", newProjectCodes, emptyRowList, invoicesResult) + return InvoiceResponse(true, "OK", newProjectCodes, emptyRowList, invoicesResult, duplicateItemsInInvoice, ArrayList()) } @Transactional(rollbackFor = [Exception::class]) @@ -294,10 +405,10 @@ open class InvoiceService( // For checking mandatory field in each row val emptyRowList: MutableList = mutableListOf() - val mandatoryColumns = listOf(0,1,4,5) // Mandatory Field in column 0,1,4,5,10,11,12 + val mandatoryColumns = listOf(0,1,4,5) // Mandatory Field in column 0,1,4,5 if (workbook == null) { - return InvoiceResponse(false, "No Excel import", newProjectCodes, emptyRowList, invoicesResult) // if workbook is null + return InvoiceResponse(false, "No Excel import", newProjectCodes, emptyRowList, invoicesResult, ArrayList(), ArrayList()) // if workbook is null } val sheet: Sheet = workbook.getSheetAt(0) @@ -307,32 +418,57 @@ open class InvoiceService( val invoices = allInvoice() val projects = projectService.allProjects() + val duplicateItemsInInvoice = checkDuplicateItemInImportedInvoice(sheet,2,0) + for (i in 2..sheet.lastRowNum){ val sheetInvoice = ExcelUtils.getCell(sheet, i, 0).stringCellValue val sheetProjectCode = ExcelUtils.getCell(sheet, i, 1).stringCellValue - checkInvocieNo(sheetInvoice, invoices, invoicesResult, false) + checkInvoiceNo(sheetInvoice, invoices, invoicesResult, false) checkProjectCode(sheetProjectCode, projects, newProjectCodes) checkMandatoryField(mandatoryColumns, sheet, i, emptyRowList, 1) - println("For: $invoicesResult") - println("For: $newProjectCodes") + sheetValues.add((mapOf("invoicesNo" to sheetInvoice, "projectCode" to sheetProjectCode))) } - if (invoicesResult.size >= 1 || - newProjectCodes.size >= 1 || - emptyRowList.size >= 1 + + if (invoicesResult.size == 0){ + val invoiceCode: MutableList> = mutableListOf() + for (sheetValue in sheetValues){ + val matched = invoices.filter{ + value -> +// println("value: -------- ${value["invoicesNo"]} ${value["projectCode"]} ") +// println("${invoice.invoiceNo} -------- ${invoice.projectCode}") +// println("invoicesNo ${value["invoicesNo"]} ${value["invoicesNo"] == invoice.invoiceNo} ${invoice.invoiceNo}") +// println("projectCode ${value["projectCode"]} ${value["projectCode"] == invoice.projectCode} ${invoice.projectCode}") + sheetValue["invoicesNo"] == value.invoiceNo && sheetValue["projectCode"] == value.projectCode + } +// println("matched: ${matched}") + if (matched.isEmpty()){ +// println("IF Matched.isNotEmpty: ${sheetValue["projectCode"]} ${sheetValue["invoicesNo"]}") + invoiceCode.add(mapOf("projectCode" to sheetValue["projectCode"]!!, "invoicesNo" to sheetValue["invoicesNo"]!!)) + } + } + if(invoiceCode.isNotEmpty()){ + return InvoiceResponse(false, "Imported Invoice's format is incorrect", newProjectCodes, emptyRowList, invoicesResult, duplicateItemsInInvoice, invoiceCode) + } + } + + if (newProjectCodes.size >= 1 || + invoicesResult.size >= 1 || + emptyRowList.size >= 1 || + duplicateItemsInInvoice.isNotEmpty() ){ println("duplicateInvoices") println(invoicesResult) - return InvoiceResponse(false, "Imported Invoice's format is incorrect", newProjectCodes, emptyRowList, invoicesResult) + return InvoiceResponse(false, "Imported Invoice's format is incorrect", newProjectCodes, emptyRowList, invoicesResult, duplicateItemsInInvoice, ArrayList()) } for (i in 2..sheet.lastRowNum){ val invoice = getInvoiceByInvoiceNo(ExcelUtils.getCell(sheet, i, 0).stringCellValue) - invoice.paidAmount = ExcelUtils.getCell(sheet, i, 5).numericCellValue + invoice.paidAmount = ExcelUtils.getCell(sheet, i, 5).numericCellValue.toBigDecimal() invoice.receiptDate = ExcelUtils.getCell(sheet, i, 4).dateCellValue.toInstant().atZone(ZoneId.systemDefault()).toLocalDate() saveAndFlush(invoice) } - return InvoiceResponse(true, "OK", newProjectCodes, emptyRowList, invoicesResult) + return InvoiceResponse(true, "OK", newProjectCodes, emptyRowList, invoicesResult, duplicateItemsInInvoice, ArrayList()) } } diff --git a/src/main/java/com/ffii/tsms/modules/project/web/InvoiceController.kt b/src/main/java/com/ffii/tsms/modules/project/web/InvoiceController.kt index 57dee3f..a8c7abd 100644 --- a/src/main/java/com/ffii/tsms/modules/project/web/InvoiceController.kt +++ b/src/main/java/com/ffii/tsms/modules/project/web/InvoiceController.kt @@ -75,6 +75,11 @@ class InvoiceController( return invoiceService.allInvoice() } + @GetMapping("/v2/allInvoices/paid") + fun allInvoice_paid_v2(): List { + return invoiceService.allInvoicePaid() + } + @PostMapping("/import/issued") fun importIssuedInvoice(request: HttpServletRequest): ResponseEntity<*> { var workbook: Workbook? = null diff --git a/src/main/java/com/ffii/tsms/modules/project/web/models/InvoiceResponse.kt b/src/main/java/com/ffii/tsms/modules/project/web/models/InvoiceResponse.kt index af840cc..f84b09f 100644 --- a/src/main/java/com/ffii/tsms/modules/project/web/models/InvoiceResponse.kt +++ b/src/main/java/com/ffii/tsms/modules/project/web/models/InvoiceResponse.kt @@ -6,4 +6,6 @@ data class InvoiceResponse ( val projectList: List, val emptyRowList: List, val invoiceList: List, + val duplicateItem: List, + val paymentMilestones: List> ) \ No newline at end of file diff --git a/src/main/java/com/ffii/tsms/modules/report/service/ReportService.kt b/src/main/java/com/ffii/tsms/modules/report/service/ReportService.kt index 06fd2ab..c1ddc56 100644 --- a/src/main/java/com/ffii/tsms/modules/report/service/ReportService.kt +++ b/src/main/java/com/ffii/tsms/modules/report/service/ReportService.kt @@ -117,7 +117,7 @@ open class ReportService { } getCell(2).apply { - setCellValue(actualIncome) + setCellValue(actualIncome.toDouble()) cellStyle.dataFormat = accountingStyle } } @@ -158,7 +158,7 @@ open class ReportService { } getCell(2).apply { - setCellValue(invoice.paidAmount!!) + setCellValue(invoice.paidAmount!!.toDouble()) cellStyle.dataFormat = accountingStyle }