add excel import and export

This commit is contained in:
arsalan 2024-01-22 18:32:24 +05:30
parent 0b75681236
commit 2fecc4b3fd
3 changed files with 360 additions and 14 deletions

View File

@ -38,6 +38,8 @@ dependencies {
implementation("org.apache.httpcomponents:httpclient:4.5.14")
implementation("org.apache.poi:poi:5.0.0")
implementation("org.apache.poi:poi-ooxml:5.0.0")
implementation("com.google.code.gson:gson:2.8.8")
api ("net.cactusthorn.config:config-core:0.81")
api ("net.cactusthorn.config:config-yaml:0.81")
kapt("net.cactusthorn.config:config-compiler:0.81")

View File

@ -1,13 +1,28 @@
package com.restapi.controllers
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 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.ss.usermodel.Cell
import org.apache.poi.ss.usermodel.CellType
import org.apache.poi.ss.usermodel.DateUtil
import org.apache.poi.ss.usermodel.Workbook
import org.apache.poi.ss.usermodel.WorkbookFactory
import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream
enum class DataType {
QUOTE, PO, VENDOR
}
import java.text.SimpleDateFormat
import java.time.LocalDate
import java.time.ZoneId
import java.util.*
fun createHeaderRow(cols :List<String>, sh :HSSFSheet) {
sh.createRow(0).apply {
cols.forEachIndexed{index, value ->
@ -15,14 +30,340 @@ fun createHeaderRow(cols :List<String>, sh :HSSFSheet) {
}
}
}
fun ExportToExcel(cols :List<String>, data :List<List<String>>) {
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 enumFromCellHelper(cell: Cell, enumFor: EnumFor) :String{
var string = ""
val cellValue = cell.stringCellValue
when(enumFor){
EnumFor.UOM -> {
string = "uom"
}
EnumFor.DocType -> {
string = "doc"
}
}
return string
}
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 ExportQuotations(quotes :List<Quotation>) {
val wb = HSSFWorkbook()
val sh = wb.createSheet()
createHeaderRow(cols, sh)
for((rowCount, row) in data.withIndex()) {
sh.createRow(rowCount).apply{
for((colCount, cell) in row.withIndex()) {
createCell(colCount).setCellValue(cell)
val headers : List<String> = 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)
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<Vendor>){
val wb = HSSFWorkbook()
val sh = wb.createSheet()
val headers : List<String> = listOf("Name", "MSME", "GST Number", "Address", "Rating", "Contact Name", "Contact Email", "Contact Mobile")
createHeaderRow(headers, sh)
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<Product>){
val wb = HSSFWorkbook()
val sh = wb.createSheet()
val headers : List<String> = listOf("Id", "Name", "Description", "HSN Code", "UOM")
createHeaderRow(headers, sh)
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<PurchaseOrder>){
val wb = HSSFWorkbook()
val sh = wb.createSheet()
val headers : List<String> = 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)
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")
}
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, Product Uom, Total Amount, RFQ Number, Quote Date, Valid Till, TNC[], Documents[]
val quotesMap : MutableMap<String, Quotation> = mutableMapOf()
val quotesList : List<Quotation> = mutableListOf()
sh.rowIterator().forEach { row ->
if(row == null){
//reached eof
return@forEach
}
val quoteNum = stringFromCellHelper(row.getCell(0))
val quoteDate = 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 prodUom = enumFromCellHelper(row.getCell(10), EnumFor.UOM)
val totalQuoteAmount = doubleFromCellHelper(row.getCell(11))
val prod = POProducts("", prodName, prodUnitPrice, prodQuantity)
if (quotesMap.containsKey(quoteNum)) {
//duplicated row
quotesMap.get(quoteNum)?.products?.add(prod)
}else {
val vendor = Vendor()
vendor.name = vendorName
vendor.address = vendorAddress
vendor.gstNumber = vendorGstNum
val quote = Quotation()
quote.quoteNum = quoteNum
quote.quoteDate = quoteDate
quote.reqForQuoteNum = rfqNum
quote.validTill = quoteValidTill
quote.products = mutableListOf<POProducts>(prod)
quote.vendor = vendor
quote.totalAmount = totalQuoteAmount
quotesMap.put(quoteNum, 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<String, PurchaseOrder> = 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.ALL
}
}
}
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
}
}
}

View File

@ -12,7 +12,9 @@ import java.time.LocalDateTime
import javax.persistence.*
data class Comments(val text: String = "", val by: String = "", val at: LocalDateTime = LocalDateTime.now())
data class POProducts(val productId: String = "", val unitPrice :Double = 0.0, val quantity: Double = 0.0, val description :String = "")
data class POProducts(val productId: String = "", val productName: String = "", val unitPrice :Double = 0.0, val quantity: Double = 0.0, val description :String = "")
enum class ApprovalStatus {
PENDING, APPROVED, REJECTED
}
@ -259,7 +261,7 @@ open class PurchaseOrder :BaseTenantModel() {
@ManyToOne
var vendor :Vendor? = null
var referenceQuotation :String = ""
var totalAmount :Int = 0
var totalAmount :Double = 0.0
var poNum: String = ""
var poDate: LocalDate? = null
var validTill: LocalDate? = null
@ -274,7 +276,7 @@ enum class UOM {
}
@Entity
open class Product :BaseTenantModel() {
var id: Int? = null
var id: Long? = null
var name :String = ""
var description :String = ""
var hsnCode :String = ""
@ -288,7 +290,7 @@ open class Quotation :BaseTenantModel() {
var products :MutableList<POProducts> = mutableListOf()
@ManyToOne
var vendor :Vendor? = null
var totalAmount :Long = 0
var totalAmount :Double = 0.0
var reqForQuoteNum: String = ""
var quoteNum: String = ""
@ -309,7 +311,8 @@ open class Document :BaseTenantModel() {
var name :String = ""
@Enumerated(EnumType.STRING)
var typeOfDoc :DocType? = null
var refId: Long? = null
//could be quoteNum, PoNum, InvoiceNum
var refId: String? = null
var description :String = ""
var url :String = ""
var docDate :LocalDate? = null