some updates

This commit is contained in:
gowthaman.b 2024-02-08 17:50:08 +05:30
parent d8a4483c3c
commit 40933a2713
10 changed files with 301 additions and 185 deletions

4
api.log Normal file
View File

@ -0,0 +1,4 @@
17:49:29.421 [main] INFO io.ebean - ebean version: 13.23.2
17:49:29.469 [main] INFO io.avaje.config - Loaded properties from []
17:49:29.513 [main] INFO io.ebean.core - offline platform [POSTGRES]
17:49:29.918 [main] INFO io.ebean.core - Started database[db] platform[POSTGRES] in 428ms

View File

@ -42,7 +42,7 @@ class AppAccessManager : AccessManager {
Role.DbOps -> listOf("ROLE_DB_OPS") Role.DbOps -> listOf("ROLE_DB_OPS")
Role.Entity -> loadEntityActionRole(entity, action) Role.Entity -> loadEntityActionRole(entity, action)
is Role.Standard -> role.action.toList().map { "ROLE_${entity}_${it}" } is Role.Standard -> role.action.toList().map { "ROLE_${entity}_${it}" }
is Role.Explicit -> role.roles is Role.Explicit -> role.roles.toList() + listOf("ROLE_ADMIN")
}.map(String::uppercase) }.map(String::uppercase)
} }

View File

@ -112,54 +112,52 @@ fun main(args: Array<String>) {
path("/vendor") { path("/vendor") {
path("/") { path("/") {
post("", VendorCtrl::create, Roles(Role.Explicit(listOf("ROLE_VENDOR_CREATE", "ROLE_ADMIN")))) post("", VendorCtrl::create, Roles(Role.Explicit("ROLE_VENDOR_CREATE")))
post("/batch", VendorCtrl::createBatch, Roles(Role.Explicit(listOf("ROLE_VENDOR_CREATE", "ROLE_ADMIN")))) post("/batch", VendorCtrl::createBatch, Roles(Role.Explicit("ROLE_VENDOR_CREATE")))
get("/{id}", VendorCtrl::get, Roles(Role.Explicit(listOf("ROLE_VENDOR_VIEW", "ROLE_VENDOR_CREATE", "ROLE_ADMIN")))) get("/{id}", VendorCtrl::get, Roles(Role.Explicit("ROLE_VENDOR_VIEW", "ROLE_VENDOR_CREATE")))
post("/getAll", VendorCtrl::getAll, Roles(Role.Explicit(listOf("ROLE_VENDOR_VIEW", "ROLE_VENDOR_CREATE")))) post("/getAll", VendorCtrl::getAll, Roles(Role.Explicit("ROLE_VENDOR_VIEW", "ROLE_VENDOR_CREATE")))
get("quotes/{id}", VendorCtrl::getQuotes, Roles(Role.Explicit(listOf("ROLE_ADMIN", "ROLE_QUOTE_VIEW", "ROLE_QUOTE_CREATE", "ROLE_VENDOR_VIEW")))) get("quotes/{id}", VendorCtrl::getQuotes, Roles(Role.Explicit("ROLE_QUOTE_VIEW", "ROLE_QUOTE_CREATE", "ROLE_VENDOR_VIEW")))
get("pos/{id}", VendorCtrl::getPos, Roles(Role.Explicit(listOf("ROLE_ADMIN", "ROLE_PO_VIEW", "ROLE_PO_CREATE`")))) get("pos/{id}", VendorCtrl::getPos, Roles(Role.Explicit("ROLE_PO_VIEW", "ROLE_PO_CREATE`")))
put("/rate/{id}/{rating}", VendorCtrl::rate, Roles(Role.Explicit(listOf("ROLE_VENDOR_CREATE", "ROLE_ADMIN")))) put("/rate/{id}/{rating}", VendorCtrl::rate, Roles(Role.Explicit("ROLE_VENDOR_CREATE")))
} }
path("/po") { path("/po") {
get("/next", PurchaseOrderCtrl::getNextNum, Roles(Role.Explicit(listOf("ROLE_PO_CREATE", "ROLE_ADMIN")))) get("/next", PurchaseOrderCtrl::getNextNum, Roles(Role.Explicit("ROLE_PO_CREATE")))
post("", PurchaseOrderCtrl::create, Roles(Role.Explicit(listOf("ROLE_PO_CREATE", "ROLE_ADMIN")))) post("", PurchaseOrderCtrl::create, Roles(Role.Explicit("ROLE_PO_CREATE")))
post("/batch", PurchaseOrderCtrl::createBatch, Roles(Role.Explicit(listOf("ROLE_PO_CREATE", "ROLE_ADMIN")))) post("/batch", PurchaseOrderCtrl::createBatch, Roles(Role.Explicit("ROLE_PO_CREATE")))
post("/getAll", PurchaseOrderCtrl::getAll, Roles(Role.Explicit(listOf("ROLE_PO_CREATE", "ROLE_PO_VIEW", "ROLE_VENDOR_CREATE", "ROLE_ADMIN")))) post("/getAll", PurchaseOrderCtrl::getAll, Roles(Role.Explicit("ROLE_PO_CREATE", "ROLE_PO_VIEW", "ROLE_VENDOR_CREATE")))
get("/{id}", PurchaseOrderCtrl::get, Roles(Role.Explicit(listOf("ROLE_PO_CREATE", "ROLE_PO_VIEW", "ROLE_QUOTE_CREATE")))) get("/{id}", PurchaseOrderCtrl::get, Roles(Role.Explicit("ROLE_PO_CREATE", "ROLE_PO_VIEW", "ROLE_QUOTE_CREATE")))
put("/approve/{id}", PurchaseOrderCtrl::approve, Roles(Role.Explicit(listOf("ROLE_ADMIN")))) put("/approve/{id}", PurchaseOrderCtrl::approve, Roles(Role.Explicit()))
put("/reject/{id}", PurchaseOrderCtrl::reject, Roles(Role.Explicit(listOf("ROLE_ADMIN")))) put("/reject/{id}", PurchaseOrderCtrl::reject, Roles(Role.Explicit()))
get("/refQuote/{id}", PurchaseOrderCtrl::quoteReference, Roles(Role.Explicit(listOf("ROLE_PO_CREATE", "ROLE_ADMIN")))) get("/refQuote/{id}", PurchaseOrderCtrl::quoteReference, Roles(Role.Explicit("ROLE_PO_CREATE")))
} }
path("/quote") { path("/quote") {
get("/next", QuotationCtrl::getNextNum, Roles(Role.Explicit(listOf("ROLE_QUOTE_CREATE", "ROLE_ADMIN")))) get("/next", QuotationCtrl::getNextNum, Roles(Role.Explicit("ROLE_QUOTE_CREATE")))
post("", QuotationCtrl::create, Roles(Role.Explicit(listOf("ROLE_QUOTE_CREATE", "ROLE_ADMIN")))) post("", QuotationCtrl::create, Roles(Role.Explicit("ROLE_QUOTE_CREATE")))
post("/batch", QuotationCtrl::createBatch, Roles(Role.Explicit(listOf("ROLE_QUOTE_CREATE", "ROLE_ADMIN")))) post("/batch", QuotationCtrl::createBatch, Roles(Role.Explicit("ROLE_QUOTE_CREATE")))
post("/getAll", QuotationCtrl::getAll, Roles(Role.Explicit(listOf("ROLE_QUOTE_CREATE", "ROLE_ADMIN", "ROLE_QUOTE_VIEW")))) post("/getAll", QuotationCtrl::getAll, Roles(Role.Explicit("ROLE_QUOTE_CREATE", "ROLE_QUOTE_VIEW")))
get("/{id}", QuotationCtrl::get, Roles(Role.Explicit(listOf("ROLE_QUOTE_VIEW", "ROLE_ADMIN", "ROLE_QUOTE_CREATE")))) get("/{id}", QuotationCtrl::get, Roles(Role.Explicit("ROLE_QUOTE_VIEW", "ROLE_QUOTE_CREATE")))
delete("/{id}", QuotationCtrl::delete, Roles(Role.Explicit(listOf("ROLE_QUOTE_CREATE", "ROLE_ADMIN")))) delete("/{id}", QuotationCtrl::delete, Roles(Role.Explicit("ROLE_QUOTE_CREATE")))
} }
path("/product") { path("/product") {
post("", ProductCtrl::create, Roles(Role.Explicit(listOf("ROLE_PRODUCT_CREATE", "ROLE_ADMIN")))) post("", ProductCtrl::create, Roles(Role.Explicit("ROLE_PRODUCT_CREATE")))
//get("/{hsnCode}", ProductCtrl::get, Roles(Role.Explicit(listOf("ROLE_PRODUCT_VIEW", "ROLE_ADMIN")))) put("/{id}", ProductCtrl::update, Roles(Role.Explicit("ROLE_PRODUCT_CREATE")))
put("/{id}", ProductCtrl::update, Roles(Role.Explicit(listOf("ROLE_PRODUCT_CREATE", "ROLE_ADMIN")))) delete("/{id}", ProductCtrl::delete, Roles(Role.Explicit("ROLE_PRODUCT_CREATE")))
//patch("/{id}", ProductCtrl::patch, Roles(Role.Explicit(listOf("ROLE_PRODUCT_UPDATE", "ROLE_ADMIN")))) patch("/{id}", ProductCtrl::patch, Roles(Role.Explicit("ROLE_PRODUCT_CREATE")))
delete("/{id}", ProductCtrl::delete, Roles(Role.Explicit(listOf("ROLE_PRODUCT_CREATE", "ROLE_ADMIN")))) get("", ProductCtrl::getAll, Roles(Role.Explicit("ROLE_PRODUCT_VIEW")))
get("", ProductCtrl::getAll, Roles(Role.Explicit(listOf("ROLE_PRODUCT_VIEW", "ROLE_ADMIN")))) get("/{id}", ProductCtrl::get, Roles(Role.Explicit("ROLE_PRODUCT_VIEW")))
get("/{id}", ProductCtrl::get, Roles(Role.Explicit(listOf("ROLE_PRODUCT_VIEW", "ROLE_ADMIN"))))
post("/getAll", ProductCtrl::getAll, Roles(Role.Explicit(listOf("ROLE_PRODUCT_VIEW", "ROLE_ADMIN"))))
} }
path("/doc") { path("/doc") {
post("", Document::create, Roles(Role.Explicit(listOf("ROLE_DOC_CREATE", "ROLE_ADMIN")))) post("", DocumentCtrl::create, Roles(Role.Explicit("ROLE_DOC_CREATE")))
//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("/{type}/{refId}", DocumentCtrl::getWithRefId, Roles(Role.Explicit("ROLE_DOC_VIEW", "ROLE_PRODUCT_CREATE")))
get("/{id}", Document::get, Roles(Role.Explicit(listOf("ROLE_DOC_VIEW", "ROLE_ADMIN", "ROLE_PRODUCT_CREATE")))) get("/{id}", DocumentCtrl::get, Roles(Role.Explicit("ROLE_DOC_VIEW", "ROLE_PRODUCT_CREATE")))
get("/print/{id}", Document::print, Roles(Role.Explicit(listOf("ROLE_DOC_CREATE", "ROLE_DOC_VIEW")))) get("/print/{id}", DocumentCtrl::print, Roles(Role.Explicit("ROLE_DOC_CREATE", "ROLE_DOC_VIEW")))
delete("/{id}", Document::delete, Roles(Role.Explicit(listOf("ROLE_DOC_CREATE")))) delete("/{id}", DocumentCtrl::delete, Roles(Role.Explicit("ROLE_DOC_CREATE")))
} }
path("/reqForQuote") { path("/reqForQuote") {
post("", RequestForQuote::create, Roles(Role.Explicit(listOf("ROLE_QUOTE_CREATE", "ROLE_PO_CREATE", "ROLE_RFQ_CREATE", "ROLE_ADMIN")))) post("", RequestForQuote::create, Roles(Role.Explicit("ROLE_QUOTE_CREATE", "ROLE_PO_CREATE", "ROLE_RFQ_CREATE")))
get("/{id}", RequestForQuote::get, Roles(Role.Explicit(listOf("ROLE_RFQ_CREATE", "ROLE_RFQ_VIEW", "ROLE_QUOTE_VIEW", "ROLE_PO_VIEW", "ROLE_ADMIN")))) get("/{id}", RequestForQuote::get, Roles(Role.Explicit("ROLE_RFQ_CREATE", "ROLE_RFQ_VIEW", "ROLE_QUOTE_VIEW", "ROLE_PO_VIEW")))
put("/{id}", RequestForQuote::update, Roles(Role.Explicit(listOf("ROLE_QUOTE_CREATE", "ROLE_PO_CREATE", "ROLE_RFQ_CREATE", "ROLE_ADMIN")))) put("/{id}", RequestForQuote::update, Roles(Role.Explicit("ROLE_QUOTE_CREATE", "ROLE_PO_CREATE", "ROLE_RFQ_CREATE")))
} }
} }
post("/script/database/{name}", Entities::executeStoredProcedure, Roles(adminRole, Role.DbOps)) post("/script/database/{name}", Entities::executeStoredProcedure, Roles(adminRole, Role.DbOps))

View File

@ -235,7 +235,7 @@ enum class Action {
sealed class Role { sealed class Role {
open class Standard(vararg val action: Action) : Role() open class Standard(vararg val action: Action) : Role()
data object Entity : Role() data object Entity : Role()
data class Explicit(val roles: List<String>) : Role() open class Explicit(vararg val roles: String) : Role()
data object DbOps : Role() data object DbOps : Role()
} }

View File

@ -6,13 +6,9 @@ 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.Quotation
import com.restapi.domain.Session.currentUser import com.restapi.domain.Session.currentUser
import com.restapi.domain.Session.database import com.restapi.domain.Session.database
import com.restapi.domain.Session.findDataModelByEntityAndUniqId import com.restapi.domain.Session.findDataModelByEntityAndUniqId
import com.restapi.domain.Vendor
import com.restapi.integ.Scripting import com.restapi.integ.Scripting
import io.ebean.CallableSql import io.ebean.CallableSql
import io.ebean.RawSqlBuilder import io.ebean.RawSqlBuilder
@ -373,6 +369,7 @@ object Entities {
false false
} }
} }
data class Filters(val common: CommonFilters, val custom: CustomFilters) data class Filters(val common: CommonFilters, val custom: CustomFilters)
data class SequenceNumber(val number: String) data class SequenceNumber(val number: String)
data class BatchPos(val pos: List<PurchaseOrder>) data class BatchPos(val pos: List<PurchaseOrder>)
@ -387,22 +384,27 @@ object PurchaseOrderCtrl {
val seq = SequenceNumber(prefix + cnt) val seq = SequenceNumber(prefix + cnt)
ctx.json(seq).status(HttpStatus.OK) ctx.json(seq).status(HttpStatus.OK)
} }
fun get(ctx: Context) { fun get(ctx: Context) {
val id = ctx.pathParam("id") val id = ctx.pathParam("id")
val po = database.find(PurchaseOrder::class.java, id) ?: throw NotFoundResponse("po not found for $id") val po = database.find(PurchaseOrder::class.java, id) ?: throw NotFoundResponse("po not found for $id")
ctx.json(po).status(HttpStatus.OK) ctx.json(po).status(HttpStatus.OK)
} }
data class PF(val common: CommonFilters, val poFilters: POFilters) data class PF(val common: CommonFilters, val poFilters: POFilters)
fun getAll(ctx: Context) { fun getAll(ctx: Context) {
val filters = ctx.bodyAsClass<PF>() val filters = ctx.bodyAsClass<PF>()
val pos = searchPos(filters.common, filters.poFilters) val pos = searchPos(filters.common, filters.poFilters)
ctx.json(pos).status(HttpStatus.OK) ctx.json(pos).status(HttpStatus.OK)
} }
fun create(ctx: Context) { fun create(ctx: Context) {
val po = ctx.bodyAsClass<PurchaseOrder>() val po = ctx.bodyAsClass<PurchaseOrder>()
database.save(po) database.save(po)
ctx.json(po).status(HttpStatus.CREATED) ctx.json(po).status(HttpStatus.CREATED)
} }
fun createBatch(ctx: Context) { fun createBatch(ctx: Context) {
val pos = ctx.bodyAsClass<List<PurchaseOrder>>() val pos = ctx.bodyAsClass<List<PurchaseOrder>>()
val txn = database.beginTransaction() val txn = database.beginTransaction()
@ -419,6 +421,7 @@ object PurchaseOrderCtrl {
} }
ctx.result("pos batch created").status(HttpStatus.CREATED) ctx.result("pos batch created").status(HttpStatus.CREATED)
} }
fun approve(ctx: Context) { fun approve(ctx: Context) {
val id = ctx.pathParam("id") val id = ctx.pathParam("id")
val po = database.find(PurchaseOrder::class.java, id) ?: throw NotFoundResponse("po not found for $id") val po = database.find(PurchaseOrder::class.java, id) ?: throw NotFoundResponse("po not found for $id")
@ -427,6 +430,7 @@ object PurchaseOrderCtrl {
ctx.json(po).status(HttpStatus.CREATED) ctx.json(po).status(HttpStatus.CREATED)
//reject all other pos pertaining to the same tx ?? //reject all other pos pertaining to the same tx ??
} }
fun reject(ctx: Context) { fun reject(ctx: Context) {
val id = ctx.pathParam("id") val id = ctx.pathParam("id")
val po = database.find(PurchaseOrder::class.java, id) ?: throw NotFoundResponse("po not found for $id") val po = database.find(PurchaseOrder::class.java, id) ?: throw NotFoundResponse("po not found for $id")
@ -434,6 +438,7 @@ object PurchaseOrderCtrl {
po.save() po.save()
ctx.json(po).status(HttpStatus.CREATED) ctx.json(po).status(HttpStatus.CREATED)
} }
fun quoteReference(ctx: Context) { fun quoteReference(ctx: Context) {
//gets the quote reference on which this po is based on //gets the quote reference on which this po is based on
val id = ctx.pathParam("id") val id = ctx.pathParam("id")
@ -462,13 +467,15 @@ object ProductCtrl {
println(product) println(product)
ctx.json(product).status(HttpStatus.OK) ctx.json(product).status(HttpStatus.OK)
} }
fun getAll(ctx: Context) { fun getAll(ctx: Context) {
val productList = Session.database.find(Product::class.java) val productList = Session.database.find(Product::class.java)
.findList() .findList()
.sortedBy { it.hsnCode } .sortedBy { it.name }
ctx.json(productList) ctx.json(productList)
} }
fun create(ctx: Context) { fun create(ctx: Context) {
val product = ctx.bodyAsClass<Product>() val product = ctx.bodyAsClass<Product>()
database.save(product) database.save(product)
@ -477,17 +484,58 @@ object ProductCtrl {
fun delete(ctx: Context) { fun delete(ctx: Context) {
val id = ctx.pathParam("id") val id = ctx.pathParam("id")
val product = database.delete(Product::class.java, id) database.delete(Product::class.java, id)
} }
fun patch(ctx: Context) { fun patch(ctx: Context) {
val id = ctx.pathParam("id")
val patchValues = ctx.bodyAsClass<Map<String, Any>>()
database.beginTransaction().use {
patchValues.entries.forEach { en ->
val key = en.key
val value = en.value
database.sqlUpdate("update products set $key = ? where id = ?").apply {
setParameter(1, value)
setParameter(2, id)
execute()
}
}
it.commit()
}
} }
fun update(ctx: Context) { fun update(ctx: Context) {
val id = ctx.pathParam("id") val id = ctx.pathParam("id")
val product = database.find(Product::class.java, id) ?: throw NotFoundResponse("product not found for $id")
val updatedProduct = ctx.bodyAsClass<Product>()
product.patchValues(updatedProduct)
product.update()
} }
@JvmStatic
fun main(args: Array<String>) {
val patchValues = mapOf("name" to 1)
val id = 1;
database.beginTransaction().use {
patchValues.entries.forEach { en ->
val key = en.key
val value = en.value
database.sqlUpdate("update product set $key = ? where sys_pk = ?").apply {
setParameter(1, value)
setParameter(2, id)
execute()
}
}
it.commit()
}
}
} }
object QuotationCtrl { object QuotationCtrl {
@ -500,13 +548,16 @@ object QuotationCtrl {
val seq = SequenceNumber(prefix + cnt) val seq = SequenceNumber(prefix + cnt)
ctx.json(seq).status(HttpStatus.OK) ctx.json(seq).status(HttpStatus.OK)
} }
fun get(ctx: Context) { fun get(ctx: Context) {
val id = ctx.pathParam("id") val id = ctx.pathParam("id")
val quote = database.find(Quotation::class.java, id) ?: throw NotFoundResponse("quote not found for $id") val quote = database.find(Quotation::class.java, id) ?: throw NotFoundResponse("quote not found for $id")
ctx.status(HttpStatus.OK) ctx.status(HttpStatus.OK)
ctx.json(quote) ctx.json(quote)
} }
data class QF(val common: CommonFilters, val quoteFilters: QuoteFilters) data class QF(val common: CommonFilters, val quoteFilters: QuoteFilters)
fun getAll(ctx: Context) { fun getAll(ctx: Context) {
val filters = ctx.bodyAsClass<QF>() val filters = ctx.bodyAsClass<QF>()
val quotes = searchQuotes(filters.common, filters.quoteFilters) val quotes = searchQuotes(filters.common, filters.quoteFilters)
@ -518,6 +569,7 @@ object QuotationCtrl {
database.save(quote) database.save(quote)
ctx.json(quote).status(HttpStatus.CREATED) ctx.json(quote).status(HttpStatus.CREATED)
} }
fun createBatch(ctx: Context) { fun createBatch(ctx: Context) {
val quotes = ctx.bodyAsClass<List<Quotation>>() val quotes = ctx.bodyAsClass<List<Quotation>>()
val txn = database.beginTransaction() val txn = database.beginTransaction()
@ -534,6 +586,7 @@ object QuotationCtrl {
} }
ctx.result("Quotes batch created").status(HttpStatus.CREATED) ctx.result("Quotes batch created").status(HttpStatus.CREATED)
} }
fun delete(ctx: Context) { fun delete(ctx: Context) {
val id = ctx.pathParam("id") val id = ctx.pathParam("id")
val quote = database.find(Quotation::class.java, id) ?: throw NotFoundResponse("quote not found for id $id") val quote = database.find(Quotation::class.java, id) ?: throw NotFoundResponse("quote not found for id $id")
@ -541,10 +594,12 @@ object QuotationCtrl {
ctx.status(HttpStatus.OK) ctx.status(HttpStatus.OK)
ctx.result("quote with $id deleted") ctx.result("quote with $id deleted")
} }
fun generatePO(ctx: Context) { fun generatePO(ctx: Context) {
//user should be redirected to a po form submission with prefilled values //user should be redirected to a po form submission with prefilled values
//create a PO object with values from the quote and then send it as body to vendor/po/create ?? //create a PO object with values from the quote and then send it as body to vendor/po/create ??
} }
fun reqForQuote(ctx: Context) { fun reqForQuote(ctx: Context) {
val reqForQuoteNum = ctx.pathParam(("rfqNum")) val reqForQuoteNum = ctx.pathParam(("rfqNum"))
val rfq = database.find(RequestForQuote::class.java) val rfq = database.find(RequestForQuote::class.java)
@ -555,22 +610,26 @@ object QuotationCtrl {
ctx.json(rfq) ctx.json(rfq)
} }
} }
object Document {
object DocumentCtrl {
fun get(ctx: Context) { fun get(ctx: Context) {
val id = ctx.pathParam("id") val id = ctx.pathParam("id")
val doc = database.find(Document::class.java, id) ?: throw NotFoundResponse("no doc found with id $id") val doc = database.find(Document::class.java, id) ?: throw NotFoundResponse("no doc found with id $id")
ctx.status(HttpStatus.OK) ctx.status(HttpStatus.OK)
ctx.json(doc) ctx.json(doc)
} }
fun create(ctx: Context) { fun create(ctx: Context) {
val doc = ctx.bodyAsClass<Document>() val doc = ctx.bodyAsClass<Document>()
database.save(doc) database.save(doc)
ctx.status(HttpStatus.CREATED) ctx.status(HttpStatus.CREATED)
ctx.json(doc) ctx.json(doc)
} }
fun print(ctx: Context) { fun print(ctx: Context) {
//would be handled in the frontend ?? //would be handled in the frontend ??
} }
fun delete(ctx: Context) { fun delete(ctx: Context) {
val id = ctx.pathParam("id") val id = ctx.pathParam("id")
val doc = database.find(Document::class.java, id) ?: throw NotFoundResponse("no doc found with id $id") val doc = database.find(Document::class.java, id) ?: throw NotFoundResponse("no doc found with id $id")
@ -578,90 +637,95 @@ object Document {
ctx.status(HttpStatus.OK) ctx.status(HttpStatus.OK)
ctx.result("document deleted with id $id") ctx.result("document deleted with id $id")
} }
fun getWithRefId(ctx: Context) { fun getWithRefId(ctx: Context) {
//fetches a particular doc (po, quote) with ref id //fetches a particular doc (po, quote) with ref id
val refId = ctx.pathParam("refId") val refId = ctx.pathParam("refId")
val doc = database.find(Document::class.java) val doc = database.find(Document::class.java)
.where() .where()
.eq("refId", refId) .eq("typeOfDoc", DocType.valueOf(ctx.pathParam("type")))
.eq("refIdOfDoc", refId)
?: throw NotFoundResponse("no doc found for refId $refId") ?: throw NotFoundResponse("no doc found for refId $refId")
ctx.status(HttpStatus.OK) ctx.status(HttpStatus.OK)
ctx.json(doc) ctx.json(doc)
} }
} }
object VendorCtrl { object VendorCtrl {
val logger = LoggerFactory.getLogger("Vendor")
fun get(ctx: Context) { fun get(ctx: Context) {
val id = ctx.pathParam("id") val id = ctx.pathParam("id")
val vendor = database.find(Vendor::class.java, id) ?: throw NotFoundResponse("no vendor found with id $id") val vendor = database.find(Vendor::class.java, id) ?: throw NotFoundResponse("no vendor found with id $id")
ctx.status(HttpStatus.OK) ctx.status(HttpStatus.OK)
ctx.json(vendor) ctx.json(vendor)
} }
data class VF(val common: CommonFilters, val vendorFilters: VendorFilters) data class VF(val common: CommonFilters, val vendorFilters: VendorFilters)
fun getAll(ctx: Context) { fun getAll(ctx: Context) {
val filters = ctx.bodyAsClass<VF>() val filters = ctx.bodyAsClass<VF>()
println(filters.common) logger.info("filters = {}", filters)
println(filters.vendorFilters)
val pos = searchVendors(filters.common, filters.vendorFilters) val pos = searchVendors(filters.common, filters.vendorFilters)
ctx.status(HttpStatus.OK) ctx.status(HttpStatus.OK)
ctx.json(pos) ctx.json(pos)
} }
fun createBatch(ctx: Context) { fun createBatch(ctx: Context) {
val vendors = ctx.bodyAsClass<List<Vendor>>() val vendors = ctx.bodyAsClass<List<Vendor>>()
val txn = database.beginTransaction() database.saveAll(vendors)
try {
txn.isBatchMode = true
for(v in vendors) database.save(v)
txn.commit()
ctx.status(HttpStatus.CREATED).result("Vendors Created")
} catch(e :Exception){
txn.rollback()
ctx.status(HttpStatus.INTERNAL_SERVER_ERROR).result("Vendor Creation failed" + e.message)
} finally {
txn.end()
}
} }
fun create(ctx: Context) { fun create(ctx: Context) {
val vendor = ctx.bodyAsClass<Vendor>() val vendor = ctx.bodyAsClass<Vendor>()
database.save(vendor) database.save(vendor)
ctx.status(HttpStatus.CREATED) ctx.status(HttpStatus.CREATED)
ctx.json(vendor) ctx.json(vendor)
} }
fun update(ctx: Context) { fun update(ctx: Context) {
} }
fun delete(ctx :Context){
} fun delete(ctx: Context) {
fun getQuotes(ctx :Context){
val id = ctx.pathParam("id") val id = ctx.pathParam("id")
val vendor = database.find(Vendor::class.java, id) ?: throw NotFoundResponse("no vendor found with id $id")
database.delete(vendor)
ctx.status(HttpStatus.OK)
}
fun getQuotes(ctx: Context) {
val id = ctx.pathParam("id").toLong()
val quotes = database.find(Quotation::class.java) val quotes = database.find(Quotation::class.java)
.where() .where()
.eq("vendor", id) .eq("vendor", database.find(Vendor::class.java, id) ?: throw NotFoundResponse("vendor not found for $id"))
.findList() .findList()
ctx.status(HttpStatus.OK) ctx.json(quotes).status(HttpStatus.OK)
ctx.json(quotes)
} }
fun getPos(ctx: Context) { fun getPos(ctx: Context) {
val id = ctx.pathParam("id") val id = ctx.pathParam("id").toLong()
val pos = database.find(PurchaseOrder::class.java) val pos = database.find(PurchaseOrder::class.java)
.where() .where()
.eq("vendor", id) .eq("vendor", database.find(Vendor::class.java, id) ?: throw NotFoundResponse("vendor not found for $id"))
.findList() .findList()
ctx.status(HttpStatus.OK) ctx.json(pos).status(HttpStatus.OK)
ctx.json(pos)
} }
fun rate(ctx: Context) { fun rate(ctx: Context) {
val id = ctx.pathParam("id") val id = ctx.pathParam("id")
val rating = ctx.pathParam("rating").toDouble() val rating1 = ctx.pathParam("rating").toDouble()
val vendor = database.find(Vendor::class.java, id) ?: throw NotFoundResponse("vendor not found for id $id")
//could place some rating validation checks database.find(Vendor::class.java, id)?.let {
vendor.rating = rating it.rating = rating1
vendor.save() it.save()
ctx.status(HttpStatus.OK) } ?: throw NotFoundResponse("vendor not found for id $id")
ctx.result("rating changed")
ctx.result("rating changed").status(HttpStatus.OK)
} }
} }
object RequestForQuote { object RequestForQuote {
fun create(ctx: Context) { fun create(ctx: Context) {
val rfq = ctx.bodyAsClass<ReqForQuote>() val rfq = ctx.bodyAsClass<ReqForQuote>()

View File

@ -411,7 +411,7 @@ fun ImportFromExcel(fileType: FileType, filePath : String) {
"invoice" -> DocType.INVOICE "invoice" -> DocType.INVOICE
else -> DocType.ALL else -> DocType.ALL
} }
doc.refId = refId doc.refIdOfDoc = refId.toLong()
doc.url = url doc.url = url
} }
} }

View File

@ -218,7 +218,6 @@ open class DataModel : BaseTenantModel() {
} }
@Entity @Entity
@Index(unique = true, name = "unique_session_id", columnNames = ["session_id"]) @Index(unique = true, name = "unique_session_id", columnNames = ["session_id"])
open class AnonSession : BaseTenantModel() { open class AnonSession : BaseTenantModel() {
@ -244,6 +243,7 @@ class SafeStringDeserializer : JsonDeserializer<String>() {
} }
data class ContactPerson(val name: String = "", val email: String = "", val mobile: String = "") data class ContactPerson(val name: String = "", val email: String = "", val mobile: String = "")
@Entity @Entity
open class Vendor : BaseTenantModel() { open class Vendor : BaseTenantModel() {
var name: String = "" var name: String = ""
@ -251,13 +251,16 @@ open class Vendor :BaseTenantModel() {
var gstNumber: String = "" var gstNumber: String = ""
var address: String = "" var address: String = ""
var rating: Double = 0.0 var rating: Double = 0.0
@DbJsonB @DbJsonB
var contacts: List<ContactPerson> = mutableListOf() var contacts: List<ContactPerson> = mutableListOf()
} }
@Entity @Entity
open class PurchaseOrder : BaseTenantModel() { open class PurchaseOrder : BaseTenantModel() {
@DbJsonB @DbJsonB
var products: MutableList<POProducts> = mutableListOf() var products: MutableList<POProducts> = mutableListOf()
@ManyToOne @ManyToOne
var vendor: Vendor? = null var vendor: Vendor? = null
var referenceQuotation: String? = "" var referenceQuotation: String? = ""
@ -265,8 +268,10 @@ open class PurchaseOrder :BaseTenantModel() {
var poNum: String = "" var poNum: String = ""
var poDate: LocalDate? = null var poDate: LocalDate? = null
var validTill: LocalDate? = null var validTill: LocalDate? = null
@DbArray @DbArray
var tnc: List<String>? = arrayListOf() var tnc: List<String>? = arrayListOf()
@DbArray @DbArray
var documents: List<String>? = arrayListOf() var documents: List<String>? = arrayListOf()
} }
@ -274,12 +279,21 @@ open class PurchaseOrder :BaseTenantModel() {
enum class UOM { enum class UOM {
NOS, LTR, MTR, ALL NOS, LTR, MTR, ALL
} }
@Entity @Entity
open class Product : BaseTenantModel() { open class Product : BaseTenantModel() {
fun patchValues(updatedProduct: Product) {
this.name = updatedProduct.name
this.description = updatedProduct.description
this.hsnCode = updatedProduct.hsnCode
this.uom = updatedProduct.uom
}
var id: Long? = null var id: Long? = null
var name: String = "" var name: String = ""
var description: String = "" var description: String = ""
var hsnCode: String = "" var hsnCode: String = ""
@Enumerated(EnumType.STRING) @Enumerated(EnumType.STRING)
var uom: UOM? = null var uom: UOM? = null
} }
@ -288,6 +302,7 @@ open class Product :BaseTenantModel() {
open class Quotation : BaseTenantModel() { open class Quotation : BaseTenantModel() {
@DbJsonB @DbJsonB
var products: MutableList<POProducts> = mutableListOf() var products: MutableList<POProducts> = mutableListOf()
@ManyToOne @ManyToOne
var vendor: Vendor? = null var vendor: Vendor? = null
var totalAmount: Double = 0.0 var totalAmount: Double = 0.0
@ -297,6 +312,7 @@ open class Quotation :BaseTenantModel() {
var vendorQuoteNum: String? = "" var vendorQuoteNum: String? = ""
var quoteDate: LocalDate? = null var quoteDate: LocalDate? = null
var validTill: LocalDate? = null var validTill: LocalDate? = null
@DbArray @DbArray
var tnc: List<String>? = arrayListOf() var tnc: List<String>? = arrayListOf()
@ -307,28 +323,33 @@ open class Quotation :BaseTenantModel() {
enum class DocType { enum class DocType {
PO, QUOTE, INVOICE, ALL 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
//could be quoteNum, PoNum, InvoiceNum //could be quoteNum, PoNum, InvoiceNum
var refId: String? = null var refIdOfDoc: Long? = null
var description: String = "" var description: String = ""
var url: String = "" var url: String = ""
var docDate: LocalDate? = null var docDate: LocalDate? = null
var vendor :Vendor? = null
} }
enum class RFQStatus { enum class RFQStatus {
DELIVERED, PO, QUOTE, CANCELLED DELIVERED, PO, QUOTE, CANCELLED
} }
@Entity @Entity
open class ReqForQuote : BaseTenantModel() { open class ReqForQuote : BaseTenantModel() {
@DbArray @DbArray
var potentialVendors: List<Long>? = null var potentialVendors: List<Long>? = null
@Enumerated(EnumType.STRING) @Enumerated(EnumType.STRING)
var status: RFQStatus? = null var status: RFQStatus? = null
// @DbArray // @DbArray
// var docs :List<Document>? = null // var docs :List<Document>? = null
@DbJsonB @DbJsonB

View File

@ -0,0 +1,2 @@
-- apply alter tables
alter table document add column if not exists ref_id_of_doc bigint;

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<migration xmlns="http://ebean-orm.github.io/xml/ns/dbmigration">
<changeSet type="apply">
<addColumn tableName="document">
<column name="ref_id_of_doc" type="bigint"/>
</addColumn>
</changeSet>
<changeSet type="pendingDrops">
<dropColumn columnName="ref_id" tableName="document"/>
</changeSet>
</migration>

View File

@ -1,4 +1,19 @@
<configuration> <configuration>
<appender name="ROLLING" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>api.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>api.%d{yyyy-MM-dd}.%i.log.gz</FileNamePattern>
<MaxHistory>30</MaxHistory>
<timeBasedFileNamingAndTriggeringPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder> <encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern> <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
@ -14,5 +29,6 @@
<root level="info"> <root level="info">
<appender-ref ref="STDOUT" /> <appender-ref ref="STDOUT" />
<appender-ref ref="ROLLING" />
</root> </root>
</configuration> </configuration>