Compare commits

11 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
arsalan
dd55cd22cf Merge branch 'master' of https://git.basuvaraj.com/gowthaman/readymixerp_modules_api 2024-01-19 15:04:08 +05:30
arsalan
aa97275b9c add filters 2024-01-19 15:03:45 +05:30
arsalan
cfdb792aa5 add filters 2024-01-19 14:58:53 +05:30
cb184dee3b product 2024-01-19 14:54:17 +05:30
043cddcaa0 product 2024-01-19 10:42:50 +05:30
7 changed files with 591 additions and 106 deletions

View File

@@ -5,14 +5,14 @@ Authorization: {{auth-token}}
{ {
"data": { "data": {
"number": "KA01HD6667", "number": "KA01HD6677",
"owner": "gowthaman" "owner": "gowthaman"
}, },
"uniqueIdentifier": "" "uniqueIdentifier": ""
} }
### create row ### create row
POST http://localhost:9001/api/vendor POST http://localhost:9001/api/vendor/po
Content-Type: application/json Content-Type: application/json
Authorization: {{auth-token}} Authorization: {{auth-token}}
@@ -58,7 +58,7 @@ Authorization: Bearer {{auth-token}}
### query row ### query row
POST http://localhost:9001/api/vehicle/query POST http://localhost:9001/api/vehicle/query
Content-Type: application/json Content-Type: application/json
Authorization: set-auth-token Authorization: {{set-auth-token}}
{ {
"sql": "select sys_pk, tenant_id, deleted_on, deleted_by, deleted, version, created_at, modified_at, created_by, modified_by, data, tags, comments, unique_identifier, entity_name from data_model where data ->> 'number' = :number", "sql": "select sys_pk, tenant_id, deleted_on, deleted_by, deleted, version, created_at, modified_at, created_by, modified_by, data, tags, comments, unique_identifier, entity_name from data_model where data ->> 'number' = :number",
@@ -93,6 +93,50 @@ Authorization: {{auth-token}}
DELETE http://localhost:9001/api/vehicle/KA01HD6667 DELETE http://localhost:9001/api/vehicle/KA01HD6667
Authorization: {{auth-token}} Authorization: {{auth-token}}
### get po for id ### get products
GET http://localhost:9001/api/vendor/po/12345 GET http://localhost:9001/api/vendor/product
Authorization: {{auth-token}}
### get products by hsn code
GET http://localhost:9001/api/vendor/product/#123
Authorization: {{auth-token}}
### 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
POST http://localhost:9001/api/vendor/product
Content-Type: application/json
Authorization: {{auth-token}}
{
"name": "Shirt",
"description": "Black Shirt",
"hsnCode": "BSM1XL"
}
### update field
PATCH http://localhost:9001/api/vendor/product/11
Content-Type: application/json
Authorization: {{auth-token}}
### upate a row
PUT http://localhost:9001/api/vendor/product/11
Content-Type: application/json
Authorization: {{auth-token}}
### delete a row
DELETE http://localhost:9001/api/vendor/product/#1
Authorization: {{auth-token}}
###
POST http://localhost:9001/api/vendor/product/import
Authorization: {{auth-token}} Authorization: {{auth-token}}

View File

@@ -36,6 +36,8 @@ dependencies {
implementation("org.yaml:snakeyaml:2.2") implementation("org.yaml:snakeyaml:2.2")
implementation("io.minio:minio:8.5.7") implementation("io.minio:minio:8.5.7")
implementation("org.apache.httpcomponents:httpclient:4.5.14") implementation("org.apache.httpcomponents:httpclient:4.5.14")
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-core:0.81")
api ("net.cactusthorn.config:config-yaml:0.81") api ("net.cactusthorn.config:config-yaml:0.81")
kapt("net.cactusthorn.config:config-compiler:0.81") kapt("net.cactusthorn.config:config-compiler:0.81")

View File

@@ -6,7 +6,8 @@ import com.restapi.config.AppConfig.Companion.appConfig
import com.restapi.config.Auth.validateAuthToken import com.restapi.config.Auth.validateAuthToken
import com.restapi.controllers.* import com.restapi.controllers.*
import com.restapi.domain.DataNotFoundException import com.restapi.domain.DataNotFoundException
import com.restapi.domain.Session import com.restapi.domain.Product
import com.restapi.domain.Session.a
import com.restapi.domain.Session.currentTenant import com.restapi.domain.Session.currentTenant
import com.restapi.domain.Session.currentUser import com.restapi.domain.Session.currentUser
import com.restapi.domain.Session.objectMapper import com.restapi.domain.Session.objectMapper
@@ -22,9 +23,9 @@ import io.javalin.http.UnauthorizedResponse
import io.javalin.http.util.NaiveRateLimit import io.javalin.http.util.NaiveRateLimit
import io.javalin.http.util.RateLimitUtil import io.javalin.http.util.RateLimitUtil
import io.javalin.json.JavalinJackson import io.javalin.json.JavalinJackson
import org.checkerframework.dataflow.qual.Pure
import org.jose4j.jwt.consumer.InvalidJwtException import org.jose4j.jwt.consumer.InvalidJwtException
import org.slf4j.LoggerFactory import org.slf4j.LoggerFactory
import java.io.InputStream
import java.security.MessageDigest import java.security.MessageDigest
import java.time.LocalDateTime import java.time.LocalDateTime
import java.util.* import java.util.*
@@ -112,46 +113,128 @@ fun main(args: Array<String>) {
it.json(mapOf("status" to true)) it.json(mapOf("status" to true))
} }
path("/vendor"){ path("/vendor") {
path("/"){ path("/") {
post("", Vendor::create, Roles(Role.Explicit(listOf("ROLE_VENDOR_CREATE", "ROLE_ADMIN")))) 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(
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`")))) 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")))) put("/rate/{id}/{rating}", Vendor::rate, Roles(Role.Explicit(listOf("ROLE_VENDOR_CREATE"))))
} }
path("/po"){ path("/po") {
post("", PurchaseOrder::create, Roles(Role.Explicit(listOf("ROLE_PO_CREATE", "ROLE_ADMIN")))) 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")))) get(
put("/approve/{id}", PurchaseOrder::approve, Roles(Role.Explicit(listOf("ROLE_ADMIN", "ROLE_APPROVE")))) "/{id}",
put("/reject/{id}", PurchaseOrder::reject, Roles(Role.Explicit(listOf("ROLE_ADMIN", "ROLE_APPROVE")))) PurchaseOrder::get,
get("/refQuote/{id}", PurchaseOrder::quoteReference, Roles(Role.Explicit(listOf("ROLE_PO_CREATE", "ROLE_PO_VIEW")))) 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"){ path("/quote") {
post("", Quotation::create, Roles(Role.Explicit(listOf("ROLE_QUOTE_CREATE", "ROLE_ADMIN")))) 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(
get("/po/{id}", Quotation::generatePO, Roles(Role.Explicit(listOf("ROLE_ADMIN", "ROLE_PO_CRETE")))) "/{id}",
get("/rfq/{rfqNum}", Quotation::reqForQuote, Roles(Role.Explicit(listOf("ROLE_QUOTE_CREATE", "ROLE_QUOTE_VIEW")))) Quotation::get,
delete("/{id}", Quotation::delete, Roles(Role.Explicit(listOf("ROLE_QUOTE_CREATE", "ROLE_ADMIN")))) 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"){ path("/product") {
post("", Product::create, Roles(Role.Explicit(listOf("ROLE_PRODUCT_CREATE", "ROLE_ADMIN")))) post("", ProductCtrl::create, Roles(Role.Explicit(listOf("ROLE_PRODUCT_CREATE", "ROLE_ADMIN"))))
get("/{id}", Product::get, Roles(Role.Explicit(listOf("ROLE_DOC_VIEW", "ROLE_ADMIN", "ROLE_PRODUCT_CREATE")))) get("/{hsnCode}", ProductCtrl::get, Roles(Role.Explicit(listOf("ROLE_PRODUCT_VIEW", "ROLE_ADMIN"))))
delete("{id}", Product::delete, Roles(Role.Explicit(listOf("ROLE_PRODUCT_CREATE", "ROLE_ADMIN")))) patch("/{id}", ProductCtrl::patch, Roles(Role.Explicit(listOf("ROLE_PRODUCT_UPDATE", "ROLE_ADMIN"))))
get("/doc/{id}", Product::getDoc, Roles(Role.Explicit(listOf("ROLE_ADMIN", "ROLE_VIEW_DOC")))) put("/{id}", ProductCtrl::update, 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"){ path("/doc") {
post("", Document::create, Roles(Role.Explicit(listOf("ROLE_DOC_CREATE", "ROLE_ADMIN")))) post("", Document::create, Roles(Role.Explicit(listOf("ROLE_DOC_CREATE", "ROLE_ADMIN"))))
//why type and refid are clubbed ?? //why type and refid are clubbed ??
get("/{type}/{refId}", Document::getWithRefId, Roles(Role.Explicit(listOf("ROLE_DOC_VIEW", "ROLE_ADMIN", "ROLE_PRODUCT_CREATE")))) get(
get("/{id}", Document::get, Roles(Role.Explicit(listOf("ROLE_DOC_VIEW", "ROLE_ADMIN", "ROLE_PRODUCT_CREATE")))) "/{type}/{refId}",
get("/print/{id}", Document::print, Roles(Role.Explicit(listOf("ROLE_DOC_CREATE", "ROLE_DOC_VIEW")))) 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")))) delete("/{id}", Document::delete, Roles(Role.Explicit(listOf("ROLE_DOC_CREATE"))))
} }
path("/reqForQuote"){ path("/reqForQuote") {
post("", ReqForQuote::create, Roles(Role.Explicit(listOf("ROLE_RFQ_CREATE")))) post("", RequestForQuote::create, Roles(Role.Explicit(listOf("ROLE_RFQ_CREATE"))))
get("/{id}", ReqForQuote::get, Roles(Role.Explicit(listOf("ROLE_RFQ_CREATE", "ROLE_RFQ_VIEW")))) get(
put("/{id}", ReqForQuote::update, Roles(Role.Explicit(listOf("ROLE_RFQ_CREATE")))) "/{id}",
RequestForQuote::get,
Roles(Role.Explicit(listOf("ROLE_RFQ_CREATE", "ROLE_RFQ_VIEW")))
)
put("/{id}", RequestForQuote::update, Roles(Role.Explicit(listOf("ROLE_RFQ_CREATE"))))
} }
} }
post("/script/database/{name}", Entities::executeStoredProcedure, Roles(adminRole, Role.DbOps)) post("/script/database/{name}", Entities::executeStoredProcedure, Roles(adminRole, Role.DbOps))
@@ -178,9 +261,9 @@ fun main(args: Array<String>) {
.exception(JsonMappingException::class.java, Exceptions.jsonMappingException) .exception(JsonMappingException::class.java, Exceptions.jsonMappingException)
.exception(InvalidJwtException::class.java, Exceptions.invalidJwtException) .exception(InvalidJwtException::class.java, Exceptions.invalidJwtException)
.start(appConfig.portNumber()) .start(appConfig.portNumber())
} }
private fun Context.getAuthHeader() = header("Authorization") private fun Context.getAuthHeader() = header("Authorization")
?.replace("Bearer ", "") ?.replace("Bearer ", "")
?.replace("Bearer: ", "") ?.replace("Bearer: ", "")
?.trim() ?.trim()

View File

@@ -6,6 +6,7 @@ import com.fasterxml.jackson.databind.JsonDeserializer
import com.fasterxml.jackson.databind.JsonNode import com.fasterxml.jackson.databind.JsonNode
import com.fasterxml.jackson.databind.annotation.JsonDeserialize import com.fasterxml.jackson.databind.annotation.JsonDeserialize
import com.restapi.domain.* import com.restapi.domain.*
import com.restapi.domain.Product
import com.restapi.domain.PurchaseOrder import com.restapi.domain.PurchaseOrder
import com.restapi.domain.Quotation import com.restapi.domain.Quotation
import com.restapi.domain.Session.currentUser import com.restapi.domain.Session.currentUser
@@ -16,7 +17,13 @@ import com.restapi.integ.Scripting
import io.ebean.CallableSql import io.ebean.CallableSql
import io.ebean.RawSqlBuilder import io.ebean.RawSqlBuilder
import io.javalin.http.* 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 org.slf4j.LoggerFactory
import java.io.File
import java.io.FileInputStream
import java.io.InputStream
import java.sql.Types import java.sql.Types
import java.time.LocalDate import java.time.LocalDate
import java.time.LocalDateTime import java.time.LocalDateTime
@@ -411,6 +418,49 @@ object PurchaseOrder {
} }
} }
data class ProductSearch(
var isSort: String? = null
)
object ProductCtrl {
fun get(ctx :Context){
val hsnCode = ctx.pathParam("hsnCode")
val product = database.find(Product::class.java, hsnCode) ?: throw NotFoundResponse("Product not found for $hsnCode")
ctx.json(product)
}
fun getAll(ctx: Context){
val productList = Session.database.find(Product::class.java)
.findList()
//.sortedBy { it.hsnCode }
ctx.json(productList)
}
fun create(ctx :Context){
val product = ctx.bodyAsClass<Product>()
database.save(product)
}
fun delete(ctx: Context) {
val id = ctx.pathParam("id")
val product = database.delete(Product::class.java, id)
}
fun patch(ctx: Context) {
}
fun update(ctx: Context) {
}
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 { object Quotation {
fun get(ctx :Context){ fun get(ctx :Context){
val id = ctx.pathParam("id") val id = ctx.pathParam("id")
@@ -451,37 +501,13 @@ object Quotation {
} }
fun reqForQuote(ctx :Context){ fun reqForQuote(ctx :Context){
val reqForQuoteNum = ctx.pathParam(("rfqNum")) val reqForQuoteNum = ctx.pathParam(("rfqNum"))
val rfq = database.find(ReqForQuote::class.java) val rfq = database.find(RequestForQuote::class.java)
.where() .where()
.eq("reqForQuoteNum", reqForQuoteNum) .eq("reqForQuoteNum", reqForQuoteNum)
?: throw NotFoundResponse("request for quote not found for this quotation") ?: throw NotFoundResponse("request for quote not found for this quotation")
ctx.json(rfq) ctx.json(rfq)
} }
} }
object Product {
fun get(ctx :Context){
val id = ctx.pathParam("id")
val product = database.find(Product::class.java, id) ?: throw NotFoundResponse("product nor found for id $id")
ctx.json(product)
}
fun create(ctx :Context){
val product = ctx.bodyAsClass<Product>()
database.save(product)
ctx.result("product created")
}
fun update(ctx :Context){
}
fun delete(ctx: Context){
val id = ctx.pathParam(("id"))
val product = database.find(Product::class.java, id) ?:throw NotFoundResponse("product not found for id $id")
//product.delete()
ctx.result("product with id $id deleted")
}
fun getDoc(ctx :Context){
}
}
object Document { object Document {
fun get(ctx :Context){ fun get(ctx :Context){
val id = ctx.pathParam("id") val id = ctx.pathParam("id")
@@ -556,9 +582,9 @@ object Vendor {
ctx.result("rating changed") ctx.result("rating changed")
} }
} }
object ReqForQuote { object RequestForQuote {
fun create(ctx :Context) { fun create(ctx :Context) {
val rfq = ctx.bodyAsClass<com.restapi.domain.ReqForQuote>() val rfq = ctx.bodyAsClass<ReqForQuote>()
database.save(rfq) database.save(rfq)
//ctx.result("request for quote created") //ctx.result("request for quote created")
//ctx.json(rfq) //ctx.json(rfq)
@@ -567,12 +593,11 @@ object ReqForQuote {
} }
fun get(ctx :Context){ fun get(ctx :Context){
val id = ctx.pathParam("id") val id = ctx.pathParam("id")
val rfq = database.find(com.restapi.domain.ReqForQuote::class.java, id) ?: throw NotFoundResponse("request for quote not found for id $id") val rfq = database.find(ReqForQuote::class.java, id) ?: throw NotFoundResponse("request for quote not found for id $id")
ctx.json(rfq) ctx.json(rfq)
} }
fun update(ctx :Context){ fun update(ctx :Context){
//shuld we compare the new body fields with preexisting ones and prepare a sql query to update those fields?? //shuld we compare the new body fields with preexisting ones and prepare a sql query to update those fields??
} }
} }

View File

@@ -0,0 +1,184 @@
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.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 ?: "")
}
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

@@ -0,0 +1,145 @@
package com.restapi.controllers
import com.restapi.domain.*
import com.restapi.domain.PurchaseOrder
import com.restapi.domain.Quotation
import java.time.LocalDate
import com.restapi.domain.Session.database
//constants
const val IGNORE = "%"
val baseDate :LocalDate = LocalDate.MIN
val maxDate :LocalDate = LocalDate.MAX
const val RATING_MAX = 10.0
const val RATING_MIN = 0.0
//common filters would be used by most of the handlers
//require a list of vendor ids to be passed
data class CommonFilters (
val fromDate :LocalDate = baseDate,
val toDate :LocalDate = maxDate,
val vendor :List<Long>? = null,
val sortAsc :Boolean = true,
val sortBy :String = IGNORE
)
data class POFilters (
val poNumLike :String = IGNORE,
val totalAmountExceeds :Long = Long.MIN_VALUE,
val totalAmountLessThan :Long = Long.MAX_VALUE,
val validAfter: LocalDate = baseDate,
val validBefore: LocalDate = maxDate,
val refQuotation :String = IGNORE,
)
data class ProductFilters (
val nameLike :String = IGNORE,
val hsnLike :String = IGNORE,
val uom :UOM = UOM.ALL,
)
data class DocumentFilters (
val nameLike :String = IGNORE,
val typeOfDoc :DocType = DocType.ALL,
)
data class RFQFilters (
val validBefore :LocalDate = maxDate,
val validAfter :LocalDate = baseDate,
val reqForQuoteNumLike :String = IGNORE,
)
data class QuoteFilters (
val quoteNumLike :String = IGNORE,
val validBefore :LocalDate = baseDate,
val validAfter :LocalDate = maxDate,
val totalAmountExceeds :Long = Long.MIN_VALUE,
val totalAmountLessThan :Long = Long.MAX_VALUE,
)
data class VendorFilters (
val nameLike :String = IGNORE,
val msmeLike :String = IGNORE,
val gstNumLike :String = IGNORE,
val addressLike :String = IGNORE,
val ratingExceeds :Double = RATING_MIN,
val ratingLessThan :Double = RATING_MAX,
)
fun<T> applyVendorHelper(q :io.ebean.ExpressionList<T>, vids :List<Long>?) {
if (vids.isNullOrEmpty()) return
q.apply {
q.`in`("vendor", vids)
}
}
fun<T> applySortHelper(q :io.ebean.ExpressionList<T>, sortBy :String, asc :Boolean) {
if(sortBy == IGNORE) return;
val order = if (asc) "ASC" else "DESC"
q.orderBy("$sortBy $order")
}
fun<T> applyCommonFilters(q :io.ebean.ExpressionList<T>, commonFilters: CommonFilters) {
applyVendorHelper<T>(q, commonFilters.vendor)
applySortHelper<T>(q, commonFilters.sortBy, commonFilters.sortAsc)
}
fun searchQuotes(commonFilters: CommonFilters, quoteFilters: QuoteFilters) : List<Quotation> {
val q = database.find(Quotation::class.java)
.where()
.between("quoteDate", commonFilters.fromDate, commonFilters.toDate)
.ilike("quoteNum", quoteFilters.quoteNumLike )
.ge("validTill",quoteFilters.validAfter)
.le("validTill", quoteFilters.validBefore)
.le("totalAmount", quoteFilters.totalAmountLessThan)
.ge("totalAmount", quoteFilters.totalAmountExceeds)
.apply {
if(!commonFilters.vendor?.isEmpty()!!){
commonFilters.vendor.let { this.`in`("vendor", it) }
}
}
applySortHelper(q, commonFilters.sortBy, commonFilters.sortAsc)
return q.findList()
}
fun searchVendors(commonFilters: CommonFilters, vendorFilters: VendorFilters) : List<Vendor> {
val q = database.find(Vendor::class.java)
.where()
.ge("rating", vendorFilters.ratingExceeds)
.le("rating", vendorFilters.ratingLessThan)
.ilike("name", vendorFilters.nameLike)
.ilike("msme", vendorFilters.msmeLike)
.ilike("gstNum", vendorFilters.gstNumLike)
.ilike("address", vendorFilters.addressLike)
applySortHelper(q, commonFilters.sortBy, commonFilters.sortAsc)
return q.findList()
}
fun searchDocs(commonFilters: CommonFilters, documentFilters: DocumentFilters) : List<Document> {
val q = database.find(Document::class.java)
.where()
.apply {
if(documentFilters.typeOfDoc != DocType.ALL){
this.eq("docType", documentFilters.typeOfDoc)
}
}
.ilike("name", documentFilters.nameLike )
applySortHelper(q, commonFilters.sortBy, commonFilters.sortAsc)
return q.findList()
}
fun searchPos(commonFilters: CommonFilters, poFilters: POFilters) : List<PurchaseOrder> {
val q = database.find(PurchaseOrder::class.java)
.where()
.between("totalAmount", poFilters.totalAmountExceeds, poFilters.totalAmountLessThan)
.between("validTill", poFilters.validAfter, poFilters.validBefore)
.ilike("poNum", poFilters.poNumLike )
.ilike("referenceQuotation", poFilters.refQuotation )
applyVendorHelper(q, commonFilters.vendor)
applySortHelper(q, commonFilters.sortBy, commonFilters.sortAsc)
return q.findList()
}
fun searchRFQ(commonFilters: CommonFilters, rfqFilters: RFQFilters) : List<ReqForQuote> {
val q = database.find(ReqForQuote::class.java)
.where()
.between("validTill", rfqFilters.validAfter, rfqFilters.validBefore)
.ilike("reqForQuoteNum", rfqFilters.reqForQuoteNumLike)
applyVendorHelper(q, commonFilters.vendor)
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 io.ebean.annotation.Index
import java.time.LocalDate import java.time.LocalDate
import java.time.LocalDateTime import java.time.LocalDateTime
import java.util.*
import javax.persistence.* import javax.persistence.*
data class Comments(val text: String = "", val by: String = "", val at: LocalDateTime = LocalDateTime.now()) data class Comments(val text: String = "", val by: String = "", val at: LocalDateTime = LocalDateTime.now())
@@ -239,7 +240,6 @@ class SafeStringDeserializer : JsonDeserializer<String>() {
if (!regex.matches(text)) throw IllegalArgumentException() if (!regex.matches(text)) throw IllegalArgumentException()
return text return text
} }
} }
data class ContactPerson(val name: String, val email: String, val mobile: String) data class ContactPerson(val name: String, val email: String, val mobile: String)
@@ -271,10 +271,12 @@ open class PurchaseOrder :BaseTenantModel() {
} }
enum class UOM { enum class UOM {
NOS, LTR, MTR NOS, LTR, MTR, ALL
} }
@Entity @Entity
open class Product :BaseTenantModel() { open class Product :BaseTenantModel() {
var id: Int? = null
var name :String = "" var name :String = ""
var description :String = "" var description :String = ""
var hsnCode :String = "" var hsnCode :String = ""
@@ -288,7 +290,7 @@ open class Quotation :BaseTenantModel() {
var products :MutableList<POProducts> = mutableListOf() var products :MutableList<POProducts> = mutableListOf()
@ManyToOne @ManyToOne
var vendor :Vendor? = null var vendor :Vendor? = null
var totalAmount :Int = 0 var totalAmount :Long = 0
var reqForQuoteNum: String = "" var reqForQuoteNum: String = ""
var quoteNum: String = "" var quoteNum: String = ""
@@ -301,14 +303,14 @@ open class Quotation :BaseTenantModel() {
var documents: MutableList<Long> = arrayListOf() var documents: MutableList<Long> = arrayListOf()
} }
enum class DOCTYPE{ enum class DocType{
PO, QUOTE, INVOICE PO, QUOTE, INVOICE, ALL
} }
@Entity @Entity
open class Document :BaseTenantModel() { open class Document :BaseTenantModel() {
var name :String = "" var name :String = ""
@Enumerated(EnumType.STRING) @Enumerated(EnumType.STRING)
var typeOfDoc :DOCTYPE? = null var typeOfDoc :DocType? = null
var refId: Long? = null var refId: Long? = null
var description :String = "" var description :String = ""
var url :String = "" var url :String = ""
@@ -327,6 +329,6 @@ open class ReqForQuote :BaseTenantModel() {
var docs :List<Document>? = null var docs :List<Document>? = null
@DbJsonB @DbJsonB
var products :List<POProducts>? = null var products :List<POProducts>? = null
var reqForQuoteNum: String? = null var reqForQuoteNum: String = ""
var openTill: LocalDate? = null var openTill: LocalDate? = null
} }