package com.restapi.controllers import com.fasterxml.jackson.databind.DeserializationFeature import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper import com.google.gson.Gson import com.restapi.domain.* import com.restapi.domain.Document import com.restapi.domain.PurchaseOrder import com.restapi.domain.Quotation import com.restapi.domain.Session.currentUser import org.apache.poi.hssf.usermodel.HSSFSheet import org.apache.poi.hssf.usermodel.HSSFWorkbook import com.restapi.domain.Session.database import com.restapi.domain.Vendor import org.apache.poi.hssf.usermodel.DVConstraint import org.apache.poi.hssf.usermodel.HSSFDataValidation import org.apache.poi.ss.usermodel.* import org.apache.poi.ss.util.CellRangeAddressList import org.apache.poi.xssf.usermodel.XSSFWorkbook import java.io.* import java.text.SimpleDateFormat import java.time.LocalDate import java.time.ZoneId import java.util.* fun createHeaderRow(cols :List, sh :HSSFSheet, wb: Workbook) { val boldFont = wb.createFont() boldFont.bold = true val style = wb.createCellStyle() style.setFont(boldFont) style.locked = true sh.createRow(0).apply { cols.forEachIndexed{index, value -> val cell = createCell(index) cell.setCellValue(value) cell.setCellStyle(style) } } } fun String.parseDate(format: String): Date? { val locale = Locale.getDefault() return try { SimpleDateFormat(format, locale).parse(this) } catch (e: Exception) { null } } fun dateFromCellHelper(cell: Cell): LocalDate?{ val date = when(cell.cellType){ CellType.STRING -> cell.stringCellValue.parseDate("yyyy-MM-dd") CellType.NUMERIC -> { if (DateUtil.isCellDateFormatted(cell)) { cell.getDateCellValue() } else{ null } } else -> null } return date?.toInstant()?.atZone(ZoneId.systemDefault())?.toLocalDate() } fun stringFromCellHelper(cell: Cell): String { val string = when(cell.cellType){ CellType.NUMERIC -> cell.numericCellValue.toString() CellType.STRING -> cell.stringCellValue else -> "" } return string } fun doubleFromCellHelper(cell: Cell): Double { val double = when(cell.cellType){ CellType.NUMERIC -> cell.numericCellValue CellType.STRING -> cell.stringCellValue.toDoubleOrNull() else -> 0.0 } return double?:0.0 } fun longIntFromCellHelper(cell : Cell) :Long { val long = when(cell.cellType){ CellType.NUMERIC -> cell.numericCellValue.toLong() CellType.STRING -> cell.stringCellValue.toLong() else -> 0 } return long } enum class FileType { QUOTES, POS, VENDORS, PRODS, DOCS } enum class EnumFor { UOM, DocType } fun saveExcelFileLocally(fileName :String, wb: Workbook){ val out = FileOutputStream(fileName) wb.use { it.write(out) } out.close() } fun TemplateExcelFile(fileType: FileType){ when(fileType){ FileType.QUOTES -> { val headers : List = listOf("Quotation Number", "Date", "Open Till", "Product Id", "Product Name", "Product Unit Price", "Quantity", "Vendor Name", "Vendor Address", "RFQ Number", "Total Amount", "Terms and Conditions") val wb = HSSFWorkbook() val sh = wb.createSheet() createHeaderRow(headers, sh, wb) saveExcelFileLocally("Quotes_Template.xls", wb) } FileType.POS -> { val headers : List = listOf("Number", "Date", "Open Till", "Reference Quotation Number", "Vendor Name", "Vendor Address", "Product Id", "Product Name", "Unit Price", "Quantity", "Total Amount", "Terms and Conditions") val wb = HSSFWorkbook() val sh = wb.createSheet() createHeaderRow(headers, sh, wb) saveExcelFileLocally("Purchase_Order_Template.xls", wb) } FileType.VENDORS -> { val headers : List = listOf("Name", "MSME", "GST Number", "Address", "Rating", "Contact Name", "Contact Email", "Contact Mobile") val wb = HSSFWorkbook() val sh = wb.createSheet() createHeaderRow(headers, sh, wb) saveExcelFileLocally("Vendors_Template.xls", wb) } FileType.PRODS -> { val headers : List = listOf("Id", "Name", "Description", "HSN Code", "UOM") val wb = HSSFWorkbook() val sh = wb.createSheet() createHeaderRow(headers, sh, wb) val r0 = CellRangeAddressList(0, 1000, 4, 4) val dv0 = HSSFDataValidation(r0, DVConstraint.createExplicitListConstraint(arrayOf("LTR", "MTR", "NOS", "ALL"))).apply { suppressDropDownArrow = true } sh.addValidationData(dv0) saveExcelFileLocally("Products_Template.xls", wb) } FileType.DOCS -> { } } } fun ExportQuotations(quotes :List) { val wb = HSSFWorkbook() val sh = wb.createSheet() val headers : List = listOf("Quotation Number", "Date", "Open Till", "Product Id", "Product Name", "Product Unit Price", "Quantity", "Vendor Name", "Vendor Address", "RFQ Number", "Total AMount", "Terms and Conditions") createHeaderRow(headers, sh, wb) val totalCols = headers.size var rowCnt = 1 for(quote in quotes){ val prodCnt = quote.products.size for (j in 0..prodCnt - 1){ val row = sh.createRow(rowCnt++) var i = 0; row.createCell(i++).setCellValue(quote.quoteNum) row.createCell(i++).setCellValue(quote.quoteDate) row.createCell(i++).setCellValue(quote.validTill) //6 would be repeated row.createCell(i++).setCellValue(quote.products[j].productId) row.createCell(i++).setCellValue(quote.products[j].productName) row.createCell(i++).setCellValue(quote.products[j].unitPrice) row.createCell(i++).setCellValue(quote.products[j].quantity) row.createCell(i++).setCellValue(quote.vendor?.name) row.createCell(i++).setCellValue(quote.vendor?.address) row.createCell(i++).setCellValue(quote.reqForQuoteNum) row.createCell(i++).setCellValue(quote.totalAmount) row.createCell(i++).setCellValue(quote.tnc.joinToString(";")) } } } fun ExportVendors(vendors :List){ val wb = HSSFWorkbook() val sh = wb.createSheet() val headers : List = listOf("Name", "MSME", "GST Number", "Address", "Rating", "Contact Name", "Contact Email", "Contact Mobile") createHeaderRow(headers, sh, wb) val totalCols = headers.size var rowCnt = 1 for (vendor in vendors){ val contactCnt = vendor.contacts.size for (j in 0..contactCnt - 1){ val row = sh.createRow(rowCnt++) var i = 0 row.createCell(i++).setCellValue(vendor.msme) row.createCell(i++).setCellValue(vendor.gstNumber) row.createCell(i++).setCellValue(vendor.address) row.createCell(i++).setCellValue(vendor.rating) row.createCell(i++).setCellValue(vendor.contacts[j].name) row.createCell(i++).setCellValue(vendor.contacts[j].email) row.createCell(i++).setCellValue(vendor.contacts[j].mobile) } } } fun ExportProds(prods :List){ val wb = HSSFWorkbook() val sh = wb.createSheet() val headers : List = listOf("Id", "Name", "Description", "HSN Code", "UOM") createHeaderRow(headers, sh, wb) val totalCols = headers.size var rowCnt = 1 for (prod in prods){ val row = sh.createRow(rowCnt++) var i = 0 row.createCell(i++).setCellValue(prod.id.toString()) row.createCell(i++).setCellValue(prod.name) row.createCell(i++).setCellValue(prod.description) row.createCell(i++).setCellValue(prod.hsnCode) row.createCell(i++).setCellValue(prod.uom?.name) } } fun ExportPos(pos :List){ val wb = HSSFWorkbook() val sh = wb.createSheet() val headers : List = listOf("Number", "Date", "Open Till", "Reference Quotation Number", "Vendor Name", "Vendor Address", "Product Id", "Product Name", "Unit Price", "Quantity", "Total Amount", "Terms and Conditions") createHeaderRow(headers, sh, wb) val totalCols = headers.size var rowCnt = 1 for(po in pos){ val prodCnt = po.products.size for (j in 0..prodCnt - 1){ val row = sh.createRow(rowCnt++) var i = 0 row.createCell(i++).setCellValue(po.poNum) row.createCell(i++).setCellValue(po.poDate) row.createCell(i++).setCellValue(po.validTill) row.createCell(i++).setCellValue(po.referenceQuotation) row.createCell(i++).setCellValue(po.vendor?.name) row.createCell(i++).setCellValue(po.vendor?.address) //6 would be repeated row.createCell(i++).setCellValue(po.products[j].productId) row.createCell(i++).setCellValue(po.products[j].productName) row.createCell(i++).setCellValue(po.products[j].unitPrice) row.createCell(i++).setCellValue(po.products[j].quantity) row.createCell(i++).setCellValue(po.totalAmount) row.createCell(i++).setCellValue(po.tnc?.joinToString(";")) } } } fun main() { //ImportFromExcel(FileType.QUOTES, "C:\\Users\\arsalan\\Downloads\\Book.xlsx") TemplateExcelFile(FileType.PRODS) } fun ImportFromExcel(fileType: FileType, filePath : String) { val wb = WorkbookFactory.create(File(filePath)) val sh = wb.getSheetAt(0) when(fileType){ FileType.QUOTES -> { //Quote Number, ProductName, Product Quantity, Total Amount, RFQ Number, Quote Date, Valid Till, TNC[], Documents[] val quotesMap : MutableMap = mutableMapOf() val quotesList : List = mutableListOf() sh.rowIterator().forEach { row -> if(row == null){ //reached eof return@forEach } val quoteNumber = stringFromCellHelper(row.getCell(0)) val quoteDt = dateFromCellHelper(row.getCell(1)) val rfqNum = stringFromCellHelper(row.getCell(2)) val quoteValidTill = dateFromCellHelper(row.getCell(3)) val vendorName = stringFromCellHelper(row.getCell(4)) val vendorGstNum = stringFromCellHelper(row.getCell(5)) val vendorAddress = stringFromCellHelper(row.getCell(6)) val prodName = stringFromCellHelper(row.getCell(7)) val prodQuantity = doubleFromCellHelper(row.getCell(8)) val prodUnitPrice = doubleFromCellHelper(row.getCell(9)) val totalQuoteAmount = doubleFromCellHelper(row.getCell(10)) val prod = POProducts("", prodName, prodUnitPrice, prodQuantity) if (quotesMap.containsKey(quoteNumber)) { //duplicated row quotesMap.get(quoteNumber)?.products?.add(prod) }else { val v = Vendor() v.apply { name = vendorName address = vendorAddress gstNumber = vendorGstNum } val quote = Quotation() quote.apply { quoteNum = quoteNumber quoteDate = quoteDt reqForQuoteNum = rfqNum validTill = quoteValidTill products = mutableListOf(prod) vendor = v totalAmount = totalQuoteAmount } quotesMap.put(quoteNumber, quote) } } //docs, tncs // println("$quotesMap") // quotesMap.forEach { (k, v) -> // println("$v") // } } FileType.POS -> { //poNum, poDate, validTill, refQuoteNum, prodName, prodQuantity, totalAmount, products, vendorName, vendorGst, vendorAddress, tnc[]. docs[] val PoMap : MutableMap = mutableMapOf() sh.rowIterator().forEach { row -> if(row == null) return@forEach val poNum = stringFromCellHelper(row.getCell(0)) val poDate = dateFromCellHelper(row.getCell(1)) val refQuoteNum = stringFromCellHelper(row.getCell(2)) val poValidTill = dateFromCellHelper(row.getCell(3)) val prodName = stringFromCellHelper(row.getCell(4)) val prodQuantity = doubleFromCellHelper(row.getCell(5)) val vendorName = stringFromCellHelper(row.getCell(6)) val vendorGstNum = stringFromCellHelper(row.getCell(7)) val vendorAddress = stringFromCellHelper(row.getCell(8)) val totalPoAmount = doubleFromCellHelper(row.getCell(9)) //tncs, docs val prod = POProducts("", prodName, 0.0, prodQuantity,"") if(PoMap.containsKey(poNum)){ //repeated row PoMap.get(poNum)?.products?.add(prod) }else{ val vendor = Vendor() vendor.name = vendorName vendor.address = vendorAddress vendor.gstNumber = vendorGstNum val po = PurchaseOrder() po.poNum = poNum po.poDate = poDate po.referenceQuotation = refQuoteNum po.validTill = poValidTill PoMap.put(poNum, po) } } } FileType.VENDORS -> { sh.rowIterator().forEach { row -> //name, msme, gstNum, addresss, rating, contacts if(row == null) return@forEach val name = stringFromCellHelper(row.getCell(0)) val msme = stringFromCellHelper(row.getCell(1)) val gstNum = stringFromCellHelper(row.getCell(2)) val address = stringFromCellHelper(row.getCell(3)) val rating = doubleFromCellHelper(row.getCell(4)) //vendor object val vendor = Vendor() vendor.name = name vendor.address = address vendor.msme = msme vendor.gstNumber = gstNum vendor.rating = rating } } FileType.PRODS -> { sh.rowIterator().forEach { row -> if(row == null) return@forEach //id, name, description, hsnCode, uom val prodId = longIntFromCellHelper(row.getCell(0)) val prodName = stringFromCellHelper(row.getCell(1)) val prodDesc = stringFromCellHelper(row.getCell(2)) val prodHsnCode = stringFromCellHelper(row.getCell(3)) val prodUom = stringFromCellHelper(row.getCell(4)) //new prod object val prod = Product() prod.id = prodId prod.name = prodName prod.description = prodDesc prod.hsnCode = prodHsnCode prod.uom = when(prodUom) { "nos" -> UOM.NOS "ltr" -> UOM.LTR "mtr" -> UOM.MTR else -> UOM.LTR } } } FileType.DOCS -> { sh.rowIterator().forEach { row -> //Document Name, Document Type, RefID, url if (row == null) return@forEach val docName = stringFromCellHelper(row.getCell(0)) val docType = stringFromCellHelper(row.getCell(1)) val refId = stringFromCellHelper(row.getCell(2)) val url = stringFromCellHelper(row.getCell(3)) //new doc object val doc = Document() doc.name = docName doc.typeOfDoc = when(docType) { "quote" -> DocType.QUOTE "po" -> DocType.PO "invoice" -> DocType.INVOICE else -> DocType.ALL } doc.refId = refId doc.url = url } } } } data class validateExcel( val name: String, val description: String, val hsnCode: String, val ok: Boolean, val err: String, ) val app_common_om = jacksonObjectMapper().apply { registerModule(JavaTimeModule()) configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) } fun ExcelRead(): String{ val inputStream = FileInputStream("C:\\Users\\vinay\\IdeaProjects\\readymixerp_modules_api_git\\Untitled 1.xlsx") val workbook = WorkbookFactory.create(inputStream) val workSheet = workbook.getSheetAt(0) var h = true //Header check if(workSheet.getRow(0).getCell(0).stringCellValue.equals("Name")) { if (workSheet.getRow(0).getCell(1).stringCellValue.equals("Description")) { if (workSheet.getRow(0).getCell(2).stringCellValue.equals("HSN")) { if (workSheet.getRow(0).getCell(3).stringCellValue.equals("UOM")) { h = false }else return "Header UOM mismatch" }else return "Header-HSN mismatch" }else return "Header-Desc mismatch" }else return "Header-Name mismatch" val resp = arrayListOf() if(h==false) { workSheet.rowIterator().forEach { row -> if (row == null) return@forEach if (h) { val pName = row.getCell(0).run { when { this == null -> "" this.cellType == CellType.STRING -> this.stringCellValue else -> "" } } val pDesc = row.getCell(1).run { when { this == null -> "" this.cellType == CellType.STRING -> this.stringCellValue else -> "" } } val pHsn = row.getCell(2).run { when { this == null -> "" this.cellType == CellType.STRING -> this.stringCellValue else -> "" } } if (pName.isEmpty() && pDesc.isEmpty() && pHsn.isEmpty()) { return@forEach } if (pName.isEmpty()) { resp.add( validateExcel( name = pName, description = pDesc, hsnCode = pHsn, ok = false, err = "Product name is required" ) ) return@forEach } if (pDesc.isEmpty()) { resp.add( validateExcel( name = pName, description = pDesc, hsnCode = pHsn, ok = false, err = "Product description is required" ) ) return@forEach } if (pHsn.isEmpty()) { resp.add( validateExcel( name = pName, description = pDesc, hsnCode = pHsn, ok = false, err = "Product HSN is required" ) ) return@forEach } } h = true } } return app_common_om.writeValueAsString(resp) } fun CreateExcel(productList: List): InputStream { val wb = XSSFWorkbook() val sh = wb.createSheet() val rows: Row = sh.createRow(0) rows.createCell(0).setCellValue("Name") rows.createCell(1).setCellValue("Description") rows.createCell(2).setCellValue("HSN") rows.createCell(3).setCellValue("UOM") var rowNum = 1 for (product in productList) { val row: Row = sh.createRow(rowNum++) row.createCell(0).setCellValue(product.name) row.createCell(1).setCellValue(product.description) row.createCell(2).setCellValue(product.hsnCode) val uomCell: Cell = row.createCell(3) uomCell.setCellValue(product.uom?.name ?: "") } val baos = ByteArrayOutputStream() wb.write(baos) wb.close() return ByteArrayInputStream(baos.toByteArray()) } fun excelToDb(): List { val inputStream = FileInputStream("C:\\Users\\vinay\\IdeaProjects\\readymixerp_modules_api_git\\Untitled 1.xlsx") val workbook = WorkbookFactory.create(inputStream) val workSheet = workbook.getSheetAt(0) for (row in workSheet) { val cell1Value = row.getCell(0).stringCellValue val cell2Value = row.getCell(1).stringCellValue val cell3Value = row.getCell(2).stringCellValue val cell4Value = row?.getCell(3)?.stringCellValue val prod = Product() prod.name = cell1Value prod.description = cell2Value prod.hsnCode = cell3Value prod.uom = when(cell4Value) { "nos" -> UOM.NOS "ltr" -> UOM.LTR "mtr" -> UOM.MTR else -> UOM.ALL } database.saveAll(prod) } val productList = Session.database.find(Product::class.java).findList() return productList }