|
|
@@ -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<String>): List<Map<String, Any>> { |
|
|
|
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<InvoiceInfo>, |
|
|
|
invoicesResult: MutableList<String>, |
|
|
|
checkDuplicate: Boolean |
|
|
|
): List<String?>{ |
|
|
|
val existingInvoiceNos: List<String?> |
|
|
|
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<String> { |
|
|
|
val uniqueValues = HashSet<String>() |
|
|
|
val duplicateValues = HashSet<String>() |
|
|
|
|
|
|
|
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<Map<String, Any>>, cellValue: Map<String, Any>): 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<Map<String, Any>> |
|
|
|
): List<Map<String, Any>> { |
|
|
|
val nonExistMilestone: MutableList<Map<String, Any>> = 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<InvoiceInfo>{ |
|
|
|
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<String> = mutableListOf() |
|
|
|
val projectsCodes: MutableList<String> = mutableListOf() |
|
|
|
|
|
|
|
// For checking mandatory field in each row |
|
|
|
val emptyRowList: MutableList<Int> = 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<Map<String, Any>> = ArrayList() |
|
|
|
// val sheetValues: MutableList<Map<String, Any>> = 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<Int> = 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<Map<String,Any>> = 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()) |
|
|
|
} |
|
|
|
} |