diff --git a/api.http b/api.http index 036e066..88f5c2d 100644 --- a/api.http +++ b/api.http @@ -359,3 +359,24 @@ Authorization: {{auth-token}} "quoteFilters": {} } + +### GET ALL PRODUCTS +POST http://localhost:9001/api/vendor/product/getAll +Content-Type: application/json +Authorization: {{auth-token}} + +{ + "common" : {}, + "quoteFilters": {} +} + +### GET NEXT PO SEQ NUMBER +GET http://localhost:9001/api/vendor/po/next +Content-Type: application/json +Authorization: {{auth-token}} + + +### GET NEXT QUOTE SEW NUMBER +GET http://localhost:9001/api/vendor/quote/next +Content-Type: application/json +Authorization: {{auth-token}} diff --git a/src/main/kotlin/com/restapi/Main.kt b/src/main/kotlin/com/restapi/Main.kt index 135cbde..3e253bf 100644 --- a/src/main/kotlin/com/restapi/Main.kt +++ b/src/main/kotlin/com/restapi/Main.kt @@ -118,33 +118,35 @@ fun main(args: Array) { post("/getAll", VendorCtrl::getAll, Roles(Role.Explicit(listOf("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("pos/{id}", VendorCtrl::getPos, Roles(Role.Explicit(listOf("ROLE_ADMIN", "ROLE_PO_VIEW", "ROLE_PO_CREATE`")))) - put("/rate/{id}/{rating}", VendorCtrl::rate, Roles(Role.Explicit(listOf("ROLE_VENDOR_CREATE")))) + put("/rate/{id}/{rating}", VendorCtrl::rate, Roles(Role.Explicit(listOf("ROLE_VENDOR_CREATE", "ROLE_ADMIN")))) } path("/po"){ + get("/next", PurchaseOrderCtrl::getNextNum, Roles(Role.Explicit(listOf("ROLE_PO_CREATE", "ROLE_ADMIN")))) post("", PurchaseOrderCtrl::create, Roles(Role.Explicit(listOf("ROLE_PO_CREATE", "ROLE_ADMIN")))) - post("/batch", PurchaseOrderCtrl::createBatch, Roles(Role.Explicit(listOf("ROLE_PO_CREATE", "ROLE_VENDOR_CREATE", "ROLE_ADMIN")))) - post("/getAll", PurchaseOrderCtrl::getAll, Roles(Role.Explicit(listOf("ROLE_PO_CREATE", "ROLE_PO_CREATE", "ROLE_VENDOR_CREATE", "ROLE_ADMIN")))) + post("/batch", PurchaseOrderCtrl::createBatch, Roles(Role.Explicit(listOf("ROLE_PO_CREATE", "ROLE_ADMIN")))) + post("/getAll", PurchaseOrderCtrl::getAll, Roles(Role.Explicit(listOf("ROLE_PO_CREATE", "ROLE_PO_VIEW", "ROLE_VENDOR_CREATE", "ROLE_ADMIN")))) get("/{id}", PurchaseOrderCtrl::get, Roles(Role.Explicit(listOf("ROLE_PO_CREATE", "ROLE_PO_VIEW", "ROLE_QUOTE_CREATE")))) - put("/approve/{id}", PurchaseOrderCtrl::approve, Roles(Role.Explicit(listOf("ROLE_ADMIN", "ROLE_APPROVE")))) - put("/reject/{id}", PurchaseOrderCtrl::reject, Roles(Role.Explicit(listOf("ROLE_ADMIN", "ROLE_APPROVE")))) - get("/refQuote/{id}", PurchaseOrderCtrl::quoteReference, Roles(Role.Explicit(listOf("ROLE_PO_CREATE", "ROLE_PO_VIEW")))) + put("/approve/{id}", PurchaseOrderCtrl::approve, Roles(Role.Explicit(listOf("ROLE_ADMIN")))) + put("/reject/{id}", PurchaseOrderCtrl::reject, Roles(Role.Explicit(listOf("ROLE_ADMIN")))) + get("/refQuote/{id}", PurchaseOrderCtrl::quoteReference, Roles(Role.Explicit(listOf("ROLE_PO_CREATE", "ROLE_ADMIN")))) } path("/quote"){ + get("/next", QuotationCtrl::getNextNum, Roles(Role.Explicit(listOf("ROLE_QUOTE_CREATE", "ROLE_ADMIN")))) post("", QuotationCtrl::create, Roles(Role.Explicit(listOf("ROLE_QUOTE_CREATE", "ROLE_ADMIN")))) - post("/batch", QuotationCtrl::createBatch, Roles(Role.Explicit(listOf("ROLE_QUOTE_CREATE", "ROLE_ADMIN", "ROLE_VENDOR_CREATE")))) - post("/getAll", QuotationCtrl::getAll, Roles(Role.Explicit(listOf("ROLE_QUOTE_CREATE", "ROLE_ADMIN", "ROLE_VENDOR_CREATE")))) - get("/{id}", QuotationCtrl::get, Roles(Role.Explicit(listOf("ROLE_QUOTE_VIEW", "ROLE_ADMIN", "ROLE_PO_CREATE", "ROLE_QUOTE_CREATE")))) - get("/po/{id}", QuotationCtrl::generatePO, Roles(Role.Explicit(listOf("ROLE_ADMIN", "ROLE_PO_CRETE")))) - get("/rfq/{rfqNum}", QuotationCtrl::reqForQuote, Roles(Role.Explicit(listOf("ROLE_QUOTE_CREATE", "ROLE_QUOTE_VIEW")))) + post("/batch", QuotationCtrl::createBatch, Roles(Role.Explicit(listOf("ROLE_QUOTE_CREATE", "ROLE_ADMIN")))) + post("/getAll", QuotationCtrl::getAll, Roles(Role.Explicit(listOf("ROLE_QUOTE_CREATE", "ROLE_ADMIN", "ROLE_QUOTE_VIEW")))) + get("/{id}", QuotationCtrl::get, Roles(Role.Explicit(listOf("ROLE_QUOTE_VIEW", "ROLE_ADMIN", "ROLE_QUOTE_CREATE")))) delete("/{id}", QuotationCtrl::delete, Roles(Role.Explicit(listOf("ROLE_QUOTE_CREATE", "ROLE_ADMIN")))) } path("/product"){ - post("", ProductCtrl::create, Roles(Role.Explicit(listOf("ROLE_PRODUCT_CREATE", "ROLE_ADMIN", "ROLE_VENDOR_CREATE")))) + 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")))) - put("/{id}", ProductCtrl::update, Roles(Role.Explicit(listOf("ROLE_PRODUCT_UPDATE", "ROLE_ADMIN")))) + put("/{id}", ProductCtrl::update, Roles(Role.Explicit(listOf("ROLE_PRODUCT_CREATE", "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")))) + delete("/{id}", ProductCtrl::delete, Roles(Role.Explicit(listOf("ROLE_PRODUCT_CREATE", "ROLE_ADMIN")))) get("", ProductCtrl::getAll, Roles(Role.Explicit(listOf("ROLE_PRODUCT_VIEW", "ROLE_ADMIN")))) + 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"){ post("", Document::create, Roles(Role.Explicit(listOf("ROLE_DOC_CREATE", "ROLE_ADMIN")))) @@ -155,9 +157,9 @@ fun main(args: Array) { 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")))) - put("/{id}", RequestForQuote::update, Roles(Role.Explicit(listOf("ROLE_RFQ_CREATE")))) + post("", RequestForQuote::create, Roles(Role.Explicit(listOf("ROLE_QUOTE_CREATE", "ROLE_PO_CREATE", "ROLE_RFQ_CREATE", "ROLE_ADMIN")))) + get("/{id}", RequestForQuote::get, Roles(Role.Explicit(listOf("ROLE_RFQ_CREATE", "ROLE_RFQ_VIEW", "ROLE_QUOTE_VIEW", "ROLE_PO_VIEW", "ROLE_ADMIN")))) + put("/{id}", RequestForQuote::update, Roles(Role.Explicit(listOf("ROLE_QUOTE_CREATE", "ROLE_PO_CREATE", "ROLE_RFQ_CREATE", "ROLE_ADMIN")))) } } post("/script/database/{name}", Entities::executeStoredProcedure, Roles(adminRole, Role.DbOps)) diff --git a/src/main/kotlin/com/restapi/controllers/Entities.kt b/src/main/kotlin/com/restapi/controllers/Entities.kt index d6d6ff2..715297a 100644 --- a/src/main/kotlin/com/restapi/controllers/Entities.kt +++ b/src/main/kotlin/com/restapi/controllers/Entities.kt @@ -374,8 +374,19 @@ object Entities { } } data class Filters(val common :CommonFilters, val custom :CustomFilters) +data class SequenceNumber(val number:String) data class BatchPos(val pos :List) object PurchaseOrderCtrl { + + fun getNextNum(ctx: Context){ + val prefix = "PO/" + val cnt = database.find(PurchaseOrder::class.java) + .findCount() + .toString() + .padStart(6, '0') + val seq = SequenceNumber(prefix + cnt) + ctx.json(seq).status(HttpStatus.OK) + } fun get(ctx :Context){ val id = ctx.pathParam("id") val po = database.find(PurchaseOrder::class.java, id) ?: throw NotFoundResponse("po not found for $id") @@ -441,10 +452,15 @@ data class ProductSearch( 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) + val id = ctx.pathParam("id") + val product = database.find(Product::class.java) + .where() + .eq("sys_pk", id.toLong()) + .findOne() + ?: throw NotFoundResponse("Product not found for $id") + println("Product found") + println(product) + ctx.json(product).status(HttpStatus.OK) } fun getAll(ctx: Context){ val productList = Session.database.find(Product::class.java) @@ -475,6 +491,15 @@ object ProductCtrl { } object QuotationCtrl { + fun getNextNum(ctx: Context){ + val prefix = "QUOTE/" + val cnt = database.find(Quotation::class.java) + .findCount() + .toString() + .padStart(6, '0') + val seq = SequenceNumber(prefix + cnt) + ctx.json(seq).status(HttpStatus.OK) + } fun get(ctx :Context){ val id = ctx.pathParam("id") val quote = database.find(Quotation::class.java, id) ?: throw NotFoundResponse("quote not found for $id") @@ -490,27 +515,8 @@ object QuotationCtrl { fun create(ctx :Context){ val quote = ctx.bodyAsClass() - //we have to check if the quotation created date is below the expiry of rfq - val rfq = database.find(com.restapi.domain.ReqForQuote::class.java) - .where() - .eq("reqForQuoteNum", quote.reqForQuoteNum) - .findOne() - if(rfq != null){ - //compare dates - if(quote.quoteDate!! <= rfq.openTill) { - //valid - database.save(quote) - ctx.status(HttpStatus.CREATED) - ctx.json(quote) - }else { - ctx.status(HttpStatus.BAD_REQUEST) - ctx.result("request for quote closed") - } - }else { - throw NotFoundResponse("request for quote not found for this quotation") - } - - + database.save(quote) + ctx.json(quote).status(HttpStatus.CREATED) } fun createBatch(ctx :Context){ val quotes = ctx.bodyAsClass>() diff --git a/src/main/kotlin/com/restapi/controllers/Excel.kt b/src/main/kotlin/com/restapi/controllers/Excel.kt index f157c23..6cd621b 100644 --- a/src/main/kotlin/com/restapi/controllers/Excel.kt +++ b/src/main/kotlin/com/restapi/controllers/Excel.kt @@ -169,7 +169,7 @@ fun ExportQuotations(quotes :List) { row.createCell(i++).setCellValue(quote.reqForQuoteNum) row.createCell(i++).setCellValue(quote.totalAmount) - row.createCell(i++).setCellValue(quote.tnc.joinToString(";")) + row.createCell(i++).setCellValue(quote.tnc?.joinToString(";")) } } } diff --git a/src/main/kotlin/com/restapi/controllers/Filters.kt b/src/main/kotlin/com/restapi/controllers/Filters.kt index 40c6352..b2ad26c 100644 --- a/src/main/kotlin/com/restapi/controllers/Filters.kt +++ b/src/main/kotlin/com/restapi/controllers/Filters.kt @@ -62,9 +62,12 @@ data class VendorFilters ( ) :CustomFilters fun applyVendorHelper(q :io.ebean.ExpressionList, vids :List?) { if (vids.isNullOrEmpty()) return - q.apply { - q.`in`("vendor", vids) - } +// q.apply { +// q.`in`("vendor", vids) +// } +// println(vids) +// println(vids[0]) + q.eq("vendor_sys_pk", vids[0]) } fun applySortHelper(q :io.ebean.ExpressionList, sortBy :String, asc :Boolean) { if(sortBy == IGNORE) return; @@ -89,6 +92,7 @@ fun searchQuotes(commonFilters: CommonFilters, quoteFilters: QuoteFilters) : Lis .ge("totalAmount", quoteFilters.totalAmountExceeds) .le("totalAmount", quoteFilters.totalAmountLessThan) .ilike("quoteNum", "%" + quoteFilters.quoteNumLike + "%") + applyFromToHelper(q, commonFilters.fromDate, commonFilters.toDate, "quoteDate") applyVendorHelper(q, commonFilters.vendor) applySortHelper(q, commonFilters.sortBy, commonFilters.sortAsc) return q.findList() @@ -128,6 +132,7 @@ fun searchPos(commonFilters: CommonFilters, poFilters: POFilters?) : List? = arrayListOf() @DbArray - var documents: MutableList? = arrayListOf() + var documents: List? = arrayListOf() } enum class UOM { @@ -294,13 +294,14 @@ open class Quotation :BaseTenantModel() { var reqForQuoteNum: String? = "" var quoteNum: String = "" + var vendorQuoteNum: String? = "" var quoteDate: LocalDate? = null var validTill: LocalDate? = null @DbArray - var tnc: List = arrayListOf() + var tnc: List? = arrayListOf() @DbArray - var documents: MutableList = arrayListOf() + var documents: List? = arrayListOf() } enum class DocType{ diff --git a/src/main/resources/dbmigration/1.4.sql b/src/main/resources/dbmigration/1.4.sql new file mode 100644 index 0000000..0700fe3 --- /dev/null +++ b/src/main/resources/dbmigration/1.4.sql @@ -0,0 +1,8 @@ +-- apply alter tables +alter table purchase_order alter column tnc drop not null; +alter table purchase_order alter column documents type varchar[] using documents::varchar[]; +alter table purchase_order alter column documents drop not null; +alter table quotation alter column tnc drop not null; +alter table quotation alter column documents type varchar[] using documents::varchar[]; +alter table quotation alter column documents drop not null; +alter table quotation add column if not exists vendor_quote_num varchar(255); diff --git a/src/main/resources/dbmigration/model/1.4.model.xml b/src/main/resources/dbmigration/model/1.4.model.xml new file mode 100644 index 0000000..526b6bb --- /dev/null +++ b/src/main/resources/dbmigration/model/1.4.model.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file