Compare commits

...

6 Commits

Author SHA1 Message Date
cfa3a7e289 Excel to Db 2024-01-24 17:27:37 +05:30
d23ac5261d Excel to Db 2024-01-24 11:25:18 +05:30
976aebec5b Product Excel Validation 2024-01-23 18:18:55 +05:30
a3f7614979 Product Excel Validation 2024-01-23 16:59:25 +05:30
8745db2127 Excel R/W 2024-01-22 15:12:58 +05:30
438daacdc6 ProductFilters 2024-01-19 17:47:18 +05:30
7 changed files with 366 additions and 83 deletions

View File

@ -93,16 +93,20 @@ Authorization: {{auth-token}}
DELETE http://localhost:9001/api/vehicle/KA01HD6667
Authorization: {{auth-token}}
### get po for id
### get products
GET http://localhost:9001/api/vendor/product
Authorization: {{auth-token}}
### get product for id
GET http://localhost:9001/api/vendor/product/7
### get products by hsn code
GET http://localhost:9001/api/vendor/product/#123
Authorization: {{auth-token}}
### get row
GET http://localhost:9001/api/vendor/product/7
### create excel for products
POST http://localhost:9001/api/vendor/product/product-excel
Authorization: {{auth-token}}
### excel read
GET http://localhost:9001/api/vendor/product/validation
Authorization: Bearer {{auth-token}}
### create product
@ -130,5 +134,9 @@ Authorization: {{auth-token}}
### delete a row
DELETE http://localhost:9001/api/vendor/product/2
DELETE http://localhost:9001/api/vendor/product/#1
Authorization: {{auth-token}}
###
POST http://localhost:9001/api/vendor/product/import
Authorization: {{auth-token}}

View File

@ -36,8 +36,8 @@ dependencies {
implementation("org.yaml:snakeyaml:2.2")
implementation("io.minio:minio:8.5.7")
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("org.apache.poi:poi:5.2.3")
implementation("org.apache.poi:poi-ooxml:5.2.3")
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

@ -7,7 +7,7 @@ import com.restapi.config.Auth.validateAuthToken
import com.restapi.controllers.*
import com.restapi.domain.DataNotFoundException
import com.restapi.domain.Product
import com.restapi.domain.Session
import com.restapi.domain.Session.a
import com.restapi.domain.Session.currentTenant
import com.restapi.domain.Session.currentUser
import com.restapi.domain.Session.objectMapper
@ -25,6 +25,7 @@ import io.javalin.http.util.RateLimitUtil
import io.javalin.json.JavalinJackson
import org.jose4j.jwt.consumer.InvalidJwtException
import org.slf4j.LoggerFactory
import java.io.InputStream
import java.security.MessageDigest
import java.time.LocalDateTime
import java.util.*
@ -115,44 +116,124 @@ fun main(args: Array<String>) {
path("/vendor") {
path("/") {
post("", Vendor::create, Roles(Role.Explicit(listOf("ROLE_VENDOR_CREATE", "ROLE_ADMIN"))))
get("", Vendor::get, Roles(Role.Explicit(listOf("ROLE_VENDOR_VIEW", "ROLE_VENDOR_CREATE", "ROLE_ADMIN"))))
get("quotes/{id}", Vendor::getQuotes, Roles(Role.Explicit(listOf("ROLE_ADMIN", "ROLE_QUOTE_VIEW", "ROLE_QUOTE_CREATE", "ROLE_VENDOR_VIEW"))))
get("pos/{id}", Vendor::getPos, Roles(Role.Explicit(listOf("ROLE_ADMIN", "ROLE_PO_VIEW", "ROLE_PO_CREATE`"))))
get(
"",
Vendor::get,
Roles(Role.Explicit(listOf("ROLE_VENDOR_VIEW", "ROLE_VENDOR_CREATE", "ROLE_ADMIN")))
)
get(
"quotes/{id}",
Vendor::getQuotes,
Roles(
Role.Explicit(
listOf(
"ROLE_ADMIN",
"ROLE_QUOTE_VIEW",
"ROLE_QUOTE_CREATE",
"ROLE_VENDOR_VIEW"
)
)
)
)
get(
"pos/{id}",
Vendor::getPos,
Roles(Role.Explicit(listOf("ROLE_ADMIN", "ROLE_PO_VIEW", "ROLE_PO_CREATE`")))
)
put("/rate/{id}/{rating}", Vendor::rate, Roles(Role.Explicit(listOf("ROLE_VENDOR_CREATE"))))
}
path("/po") {
post("", PurchaseOrder::create, Roles(Role.Explicit(listOf("ROLE_PO_CREATE", "ROLE_ADMIN"))))
get("/{id}", PurchaseOrder::get, Roles(Role.Explicit(listOf("ROLE_PO_CREATE", "ROLE_PO_VIEW", "ROLE_QUOTE_CREATE"))))
put("/approve/{id}", PurchaseOrder::approve, Roles(Role.Explicit(listOf("ROLE_ADMIN", "ROLE_APPROVE"))))
put("/reject/{id}", PurchaseOrder::reject, Roles(Role.Explicit(listOf("ROLE_ADMIN", "ROLE_APPROVE"))))
get("/refQuote/{id}", PurchaseOrder::quoteReference, Roles(Role.Explicit(listOf("ROLE_PO_CREATE", "ROLE_PO_VIEW"))))
get(
"/{id}",
PurchaseOrder::get,
Roles(Role.Explicit(listOf("ROLE_PO_CREATE", "ROLE_PO_VIEW", "ROLE_QUOTE_CREATE")))
)
put(
"/approve/{id}",
PurchaseOrder::approve,
Roles(Role.Explicit(listOf("ROLE_ADMIN", "ROLE_APPROVE")))
)
put(
"/reject/{id}",
PurchaseOrder::reject,
Roles(Role.Explicit(listOf("ROLE_ADMIN", "ROLE_APPROVE")))
)
get(
"/refQuote/{id}",
PurchaseOrder::quoteReference,
Roles(Role.Explicit(listOf("ROLE_PO_CREATE", "ROLE_PO_VIEW")))
)
}
path("/quote") {
post("", Quotation::create, Roles(Role.Explicit(listOf("ROLE_QUOTE_CREATE", "ROLE_ADMIN"))))
get("/{id}", Quotation::get, Roles(Role.Explicit(listOf("ROLE_QUOTE_VIEW", "ROLE_ADMIN", "ROLE_PO_CREATE", "ROLE_QUOTE_CREATE"))))
get("/po/{id}", Quotation::generatePO, Roles(Role.Explicit(listOf("ROLE_ADMIN", "ROLE_PO_CRETE"))))
get("/rfq/{rfqNum}", Quotation::reqForQuote, Roles(Role.Explicit(listOf("ROLE_QUOTE_CREATE", "ROLE_QUOTE_VIEW"))))
delete("/{id}", Quotation::delete, Roles(Role.Explicit(listOf("ROLE_QUOTE_CREATE", "ROLE_ADMIN"))))
get(
"/{id}",
Quotation::get,
Roles(
Role.Explicit(
listOf(
"ROLE_QUOTE_VIEW",
"ROLE_ADMIN",
"ROLE_PO_CREATE",
"ROLE_QUOTE_CREATE"
)
)
)
)
get(
"/po/{id}",
Quotation::generatePO,
Roles(Role.Explicit(listOf("ROLE_ADMIN", "ROLE_PO_CRETE")))
)
get(
"/rfq/{rfqNum}",
Quotation::reqForQuote,
Roles(Role.Explicit(listOf("ROLE_QUOTE_CREATE", "ROLE_QUOTE_VIEW")))
)
delete(
"/{id}",
Quotation::delete,
Roles(Role.Explicit(listOf("ROLE_QUOTE_CREATE", "ROLE_ADMIN")))
)
}
path("/product") {
post("", ProductCtrl::create, Roles(Role.Explicit(listOf("ROLE_PRODUCT_CREATE", "ROLE_ADMIN"))))
//get("/{hsnCode}", ProductCtrl::get, Roles(Role.Explicit(listOf("ROLE_PRODUCT_VIEW", "ROLE_ADMIN"))))
get("/{hsnCode}", ProductCtrl::get, Roles(Role.Explicit(listOf("ROLE_PRODUCT_VIEW", "ROLE_ADMIN"))))
patch("/{id}", ProductCtrl::patch, Roles(Role.Explicit(listOf("ROLE_PRODUCT_UPDATE", "ROLE_ADMIN"))))
put("/{id}", ProductCtrl::update, Roles(Role.Explicit(listOf("ROLE_PRODUCT_UPDATE", "ROLE_ADMIN"))))
//patch("/{id}", ProductCtrl::patch, Roles(Role.Explicit(listOf("ROLE_PRODUCT_UPDATE", "ROLE_ADMIN"))))
delete("/{id}", ProductCtrl::delete, Roles(Role.Explicit(listOf("ROLE_PRODUCT_DELETE", "ROLE_ADMIN"))))
get("", ProductCtrl::getAll, Roles(Role.Explicit(listOf("ROLE_PRODUCT_VIEW", "ROLE_ADMIN"))))
post("/product-excel", ProductCtrl::prodExcel)
post("/import") {ctx -> ctx.json(excelToDb())}
}
path("/doc") {
post("", Document::create, Roles(Role.Explicit(listOf("ROLE_DOC_CREATE", "ROLE_ADMIN"))))
//why type and refid are clubbed ??
get("/{type}/{refId}", Document::getWithRefId, Roles(Role.Explicit(listOf("ROLE_DOC_VIEW", "ROLE_ADMIN", "ROLE_PRODUCT_CREATE"))))
get("/{id}", Document::get, Roles(Role.Explicit(listOf("ROLE_DOC_VIEW", "ROLE_ADMIN", "ROLE_PRODUCT_CREATE"))))
get("/print/{id}", Document::print, Roles(Role.Explicit(listOf("ROLE_DOC_CREATE", "ROLE_DOC_VIEW"))))
get(
"/{type}/{refId}",
Document::getWithRefId,
Roles(Role.Explicit(listOf("ROLE_DOC_VIEW", "ROLE_ADMIN", "ROLE_PRODUCT_CREATE")))
)
get(
"/{id}",
Document::get,
Roles(Role.Explicit(listOf("ROLE_DOC_VIEW", "ROLE_ADMIN", "ROLE_PRODUCT_CREATE")))
)
get(
"/print/{id}",
Document::print,
Roles(Role.Explicit(listOf("ROLE_DOC_CREATE", "ROLE_DOC_VIEW")))
)
delete("/{id}", Document::delete, Roles(Role.Explicit(listOf("ROLE_DOC_CREATE"))))
}
path("/reqForQuote") {
post("", RequestForQuote::create, Roles(Role.Explicit(listOf("ROLE_RFQ_CREATE"))))
get("/{id}", RequestForQuote::get, Roles(Role.Explicit(listOf("ROLE_RFQ_CREATE", "ROLE_RFQ_VIEW"))))
get(
"/{id}",
RequestForQuote::get,
Roles(Role.Explicit(listOf("ROLE_RFQ_CREATE", "ROLE_RFQ_VIEW")))
)
put("/{id}", RequestForQuote::update, Roles(Role.Explicit(listOf("ROLE_RFQ_CREATE"))))
}
}

View File

@ -17,7 +17,13 @@ import com.restapi.integ.Scripting
import io.ebean.CallableSql
import io.ebean.RawSqlBuilder
import io.javalin.http.*
import org.apache.poi.ss.usermodel.Cell
import org.apache.poi.ss.usermodel.CellType
import org.apache.poi.ss.usermodel.WorkbookFactory
import org.slf4j.LoggerFactory
import java.io.File
import java.io.FileInputStream
import java.io.InputStream
import java.sql.Types
import java.time.LocalDate
import java.time.LocalDateTime
@ -414,7 +420,6 @@ object PurchaseOrder {
data class ProductSearch(
var isSort: String? = null
)
object ProductCtrl {
@ -427,7 +432,7 @@ object ProductCtrl {
fun getAll(ctx: Context){
val productList = Session.database.find(Product::class.java)
.findList()
.sortedBy { it.hsnCode }
//.sortedBy { it.hsnCode }
ctx.json(productList)
}
@ -446,9 +451,14 @@ object ProductCtrl {
}
fun update(ctx: Context) {
val id = ctx.pathParam("id")
}
fun prodExcel(it: Context) {
val product = database.find(Product::class.java).findList()
it.result(CreateExcel(product)).contentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
.header("Content-Disposition", "attachment; filename=\"product.xlsx\"")
}
}
object Quotation {

View File

@ -1,9 +1,184 @@
package com.restapi.controllers
import org.apache.poi
import java.io.FileOutputStream
enum class DataType {
QUOTE, PO, VENDOR
import com.fasterxml.jackson.databind.DeserializationFeature
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import com.restapi.domain.Product
import com.restapi.domain.Session
import com.restapi.domain.Session.database
import com.restapi.domain.UOM
import io.ebean.text.json.JsonContext
import io.javalin.http.Context
import org.apache.poi.ss.usermodel.Cell
import org.apache.poi.ss.usermodel.CellType
import org.apache.poi.ss.usermodel.Row
import org.apache.poi.ss.usermodel.WorkbookFactory
import org.apache.poi.xssf.usermodel.XSSFWorkbook
import java.io.ByteArrayInputStream
import java.io.ByteArrayOutputStream
import java.io.FileInputStream
import java.io.InputStream
fun CreateExcel(productList: List<Product>): 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 ?: "")
}
fun CreateExcel(cols :List<String>, excelFor :DataType) {
val wb = HSSFWorkbook()
val baos = ByteArrayOutputStream()
wb.write(baos)
wb.close()
return ByteArrayInputStream(baos.toByteArray())
}
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\\product-4.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<validateExcel>()
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 excelToDb(): List<Product> {
val inputStream = FileInputStream("C:\\Users\\vinay\\IdeaProjects\\readymixerp_modules_api_git\\product-4.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
}

View File

@ -1,10 +1,8 @@
package com.restapi.controllers
import com.restapi.domain.DocType
import com.restapi.domain.*
import com.restapi.domain.PurchaseOrder
import com.restapi.domain.Quotation
import com.restapi.domain.ReqForQuote
import com.restapi.domain.UOM
import java.time.LocalDate
import com.restapi.domain.Session.database
@ -136,3 +134,12 @@ fun searchRFQ(commonFilters: CommonFilters, rfqFilters: RFQFilters) : List<ReqFo
applySortHelper(q, commonFilters.sortBy, commonFilters.sortAsc)
return q.findList()
}
fun searchProduct(commonFilters: CommonFilters, productFilters: ProductFilters): List<Product> {
val p = database.find(Product::class.java)
.where()
.ilike("hsnCode", productFilters.hsnLike)
.ilike("Pname", productFilters.nameLike)
applySortHelper(p, commonFilters.sortBy, commonFilters.sortAsc)
return p.findList()
}

View File

@ -9,6 +9,7 @@ import io.ebean.annotation.*
import io.ebean.annotation.Index
import java.time.LocalDate
import java.time.LocalDateTime
import java.util.*
import javax.persistence.*
data class Comments(val text: String = "", val by: String = "", val at: LocalDateTime = LocalDateTime.now())
@ -272,6 +273,7 @@ open class PurchaseOrder :BaseTenantModel() {
enum class UOM {
NOS, LTR, MTR, ALL
}
@Entity
open class Product :BaseTenantModel() {
var id: Int? = null
@ -323,10 +325,10 @@ open class ReqForQuote :BaseTenantModel() {
var potentialVendors :List<Long>? = null
@Enumerated(EnumType.STRING)
var status :RFQStatus? = null
// @DbArray
// var docs :List<Document>? = null
@DbArray
var docs :List<Document>? = null
@DbJsonB
var products :List<POProducts>? = null
var reqForQuoteNum: String? = null
var reqForQuoteNum: String = ""
var openTill: LocalDate? = null
}