diff --git a/.idea/dataSources.xml b/.idea/dataSources.xml
index 774e527..cfa8f3c 100644
--- a/.idea/dataSources.xml
+++ b/.idea/dataSources.xml
@@ -6,6 +6,24 @@
true
org.postgresql.Driver
jdbc:postgresql://192.168.64.6:5432/uiapp
+
+
+
+
+
+
+ $ProjectFileDir$
+
+
+ postgresql
+ true
+ org.postgresql.Driver
+ jdbc:postgresql://10.10.10.211:5432/arsalan_rmc_module_app
+
+
+
+
+
$ProjectFileDir$
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
index f427e6d..94a25f7 100644
--- a/.idea/vcs.xml
+++ b/.idea/vcs.xml
@@ -1,8 +1,6 @@
-
-
\ No newline at end of file
diff --git a/api.http b/api.http
index 88d020c..5c75b21 100644
--- a/api.http
+++ b/api.http
@@ -8,7 +8,19 @@ Authorization: {{auth-token}}
"number": "KA01HD6667",
"owner": "gowthaman"
},
- "uniqueIdentifier": "KA01HD6667"
+ "uniqueIdentifier": ""
+}
+
+### create row
+POST http://localhost:9001/api/vendor
+Content-Type: application/json
+Authorization: {{auth-token}}
+
+{
+ "data": {
+ "name": "arsalan",
+ "rating": 5
+ }
}
### create row, with autogenerated identifier
@@ -23,6 +35,18 @@ Authorization: {{auth-token}}
}
}
+### create row, with autogenerated identifier
+POST http://localhost:9001/api/purchaseOrder
+Content-Type: application/json
+Authorization: {{auth-token}}
+
+{
+ "vendor" : "arslan",
+ "products": ["chairs", "tables"]
+}
+
+
+
### get row
GET http://localhost:9001/api/log/log-0000000001
Authorization: Bearer {{auth-token}}
@@ -67,4 +91,8 @@ Authorization: {{auth-token}}
### delete a row
DELETE http://localhost:9001/api/vehicle/KA01HD6667
+Authorization: {{auth-token}}
+
+### get po for id
+GET http://localhost:9001/api/vendor/po/12345
Authorization: {{auth-token}}
\ No newline at end of file
diff --git a/app-sample.yaml b/app-sample.yaml
index 9ab34ea..b46446b 100644
--- a/app-sample.yaml
+++ b/app-sample.yaml
@@ -19,6 +19,7 @@ app:
scripts:
path: /Users/gowthaman.b/IdeaProjects/rmc_modules_api/src/main/resources/scripts
security:
+ enforce_role_restriction: 'true'
private_key: |-
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQD4ba8OhlyB9MUx
diff --git a/src/main/kotlin/com/restapi/AppAccessManager.kt b/src/main/kotlin/com/restapi/AppAccessManager.kt
index 0493e28..ad84c1d 100644
--- a/src/main/kotlin/com/restapi/AppAccessManager.kt
+++ b/src/main/kotlin/com/restapi/AppAccessManager.kt
@@ -42,6 +42,7 @@ class AppAccessManager : AccessManager {
Role.DbOps -> listOf("ROLE_DB_OPS")
Role.Entity -> loadEntityActionRole(entity, action)
is Role.Standard -> role.action.toList().map { "ROLE_${entity}_${it}" }
+ is Role.Explicit -> role.roles
}.map(String::uppercase)
}
diff --git a/src/main/kotlin/com/restapi/Main.kt b/src/main/kotlin/com/restapi/Main.kt
index d2fc0d1..c63c188 100644
--- a/src/main/kotlin/com/restapi/Main.kt
+++ b/src/main/kotlin/com/restapi/Main.kt
@@ -5,6 +5,7 @@ import com.restapi.config.*
import com.restapi.config.AppConfig.Companion.appConfig
import com.restapi.config.Auth.validateAuthToken
import com.restapi.controllers.Entities
+import com.restapi.controllers.PurchaseOrder
import com.restapi.domain.DataNotFoundException
import com.restapi.domain.Session
import com.restapi.domain.Session.currentTenant
@@ -22,6 +23,7 @@ import io.javalin.http.UnauthorizedResponse
import io.javalin.http.util.NaiveRateLimit
import io.javalin.http.util.RateLimitUtil
import io.javalin.json.JavalinJackson
+import org.checkerframework.dataflow.qual.Pure
import org.jose4j.jwt.consumer.InvalidJwtException
import org.slf4j.LoggerFactory
import java.security.MessageDigest
@@ -111,6 +113,12 @@ fun main(args: Array) {
it.json(mapOf("status" to true))
}
+ path("/vendor"){
+ 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"))))
+ }
+ }
post("/script/database/{name}", Entities::executeStoredProcedure, Roles(adminRole, Role.DbOps))
post("/script/{file}/{name}", Entities::executeScript, Roles(adminRole, Role.DbOps))
diff --git a/src/main/kotlin/com/restapi/config/Auth.kt b/src/main/kotlin/com/restapi/config/Auth.kt
index 7e4be7d..f42e6fc 100644
--- a/src/main/kotlin/com/restapi/config/Auth.kt
+++ b/src/main/kotlin/com/restapi/config/Auth.kt
@@ -235,6 +235,7 @@ enum class Action {
sealed class Role {
open class Standard(vararg val action: Action) : Role()
data object Entity : Role()
+ data class Explicit(val roles: List) : Role()
data object DbOps : Role()
}
diff --git a/src/main/kotlin/com/restapi/controllers/Entities.kt b/src/main/kotlin/com/restapi/controllers/Entities.kt
index 678ec56..746319c 100644
--- a/src/main/kotlin/com/restapi/controllers/Entities.kt
+++ b/src/main/kotlin/com/restapi/controllers/Entities.kt
@@ -6,6 +6,7 @@ import com.fasterxml.jackson.databind.JsonDeserializer
import com.fasterxml.jackson.databind.JsonNode
import com.fasterxml.jackson.databind.annotation.JsonDeserialize
import com.restapi.domain.*
+import com.restapi.domain.PurchaseOrder
import com.restapi.domain.Session.currentUser
import com.restapi.domain.Session.database
import com.restapi.domain.Session.findDataModelByEntityAndUniqId
@@ -371,4 +372,17 @@ object Entities {
} catch (e: Exception) {
false
}
+}
+
+object PurchaseOrder {
+ fun get(ctx :Context){
+ val id = ctx.pathParam("id")
+ val po = database.find(PurchaseOrder::class.java, id) ?: throw NotFoundResponse("po not found for $id")
+
+ ctx.json(po)
+ }
+ fun create(ctx :Context){
+ val po = ctx.bodyAsClass()
+ database.save(po)
+ }
}
\ No newline at end of file
diff --git a/src/main/kotlin/com/restapi/domain/models.kt b/src/main/kotlin/com/restapi/domain/models.kt
index 25f230e..10a190b 100644
--- a/src/main/kotlin/com/restapi/domain/models.kt
+++ b/src/main/kotlin/com/restapi/domain/models.kt
@@ -7,11 +7,12 @@ import com.fasterxml.jackson.databind.annotation.JsonDeserialize
import io.ebean.Model
import io.ebean.annotation.*
import io.ebean.annotation.Index
+import java.time.LocalDate
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 = "")
enum class ApprovalStatus {
PENDING, APPROVED, REJECTED
}
@@ -214,6 +215,8 @@ open class DataModel : BaseTenantModel() {
}
+
+
@Entity
@Index(unique = true, name = "unique_session_id", columnNames = ["session_id"])
open class AnonSession : BaseTenantModel() {
@@ -238,3 +241,69 @@ class SafeStringDeserializer : JsonDeserializer() {
}
}
+
+data class ContactPerson(val name: String, val email: String, val mobile: String)
+@Entity
+open class Vendor :BaseTenantModel() {
+ var name :String = ""
+ var msme :String = ""
+ var gstNumber :String = ""
+ var address :String = ""
+ var rating :Double = 0.0
+ @DbJsonB
+ var contacts :List = mutableListOf()
+}
+@Entity
+open class PurchaseOrder :BaseTenantModel() {
+ @DbJsonB
+ var products :MutableList = mutableListOf()
+ @ManyToOne
+ var vendor :Vendor? = null
+ var referenceQuotation :String = ""
+ var totalAmount :Int = 0
+ var poNum: String = ""
+ var poDate: LocalDate? = null
+ var validTill: LocalDate? = null
+ @DbArray
+ var tnc: List = arrayListOf()
+ @DbArray
+ var documents: MutableList = arrayListOf()
+}
+
+enum class UOM {
+ NOS, LTR, MTR
+}
+@Entity
+open class Product :BaseTenantModel() {
+ var name :String = ""
+ var description :String = ""
+ var hsnCode :String = ""
+ @Enumerated(EnumType.STRING)
+ var uom: UOM? = null
+}
+
+@Entity
+open class Quotation :BaseTenantModel() {
+ @DbJsonB
+ var products :MutableList = mutableListOf()
+ @ManyToOne
+ var vendor :Vendor? = null
+ var totalAmount :Int = 0
+
+ var quoteNum: String = ""
+ var quoteDate: LocalDate? = null
+ var validTill: LocalDate? = null
+ @DbArray
+ var tnc: List = arrayListOf()
+
+ @DbArray
+ var documents: MutableList = arrayListOf()
+}
+
+@Entity
+open class Document :BaseTenantModel() {
+ var name :String = ""
+ var typeOfDoc :String = ""
+ var description :String = ""
+ var url :String = ""
+}
\ No newline at end of file
diff --git a/src/main/resources/dbmigration/1.2.sql b/src/main/resources/dbmigration/1.2.sql
new file mode 100644
index 0000000..6db0f64
--- /dev/null
+++ b/src/main/resources/dbmigration/1.2.sql
@@ -0,0 +1,140 @@
+-- apply changes
+create table document (
+ sys_pk bigint generated by default as identity not null,
+ deleted_on timestamp,
+ current_approval_level integer default 0 not null,
+ required_approval_levels integer default 0 not null,
+ deleted boolean default false not null,
+ version integer default 1 not null,
+ created_at timestamp default 'now()' not null,
+ modified_at timestamp default 'now()' not null,
+ deleted_by varchar(255),
+ approval_status varchar(8) default 'APPROVED' not null,
+ tags varchar[] default '{}' not null,
+ comments jsonb default '[]' not null,
+ tenant_id varchar(255) not null,
+ name varchar(255) not null,
+ type_of_doc varchar(255) not null,
+ description varchar(255) not null,
+ url varchar(255) not null,
+ created_by varchar(255) not null,
+ modified_by varchar(255) not null,
+ constraint ck_document_approval_status check ( approval_status in ('PENDING','APPROVED','REJECTED')),
+ constraint pk_document primary key (sys_pk)
+);
+
+create table product (
+ sys_pk bigint generated by default as identity not null,
+ deleted_on timestamp,
+ current_approval_level integer default 0 not null,
+ required_approval_levels integer default 0 not null,
+ deleted boolean default false not null,
+ version integer default 1 not null,
+ created_at timestamp default 'now()' not null,
+ modified_at timestamp default 'now()' not null,
+ deleted_by varchar(255),
+ approval_status varchar(8) default 'APPROVED' not null,
+ tags varchar[] default '{}' not null,
+ comments jsonb default '[]' not null,
+ tenant_id varchar(255) not null,
+ name varchar(255) not null,
+ description varchar(255) not null,
+ hsn_code varchar(255) not null,
+ uom varchar(3),
+ created_by varchar(255) not null,
+ modified_by varchar(255) not null,
+ constraint ck_product_approval_status check ( approval_status in ('PENDING','APPROVED','REJECTED')),
+ constraint ck_product_uom check ( uom in ('NOS','LTR','MTR')),
+ constraint pk_product primary key (sys_pk)
+);
+
+create table purchase_order (
+ sys_pk bigint generated by default as identity not null,
+ deleted_on timestamp,
+ current_approval_level integer default 0 not null,
+ required_approval_levels integer default 0 not null,
+ vendor_sys_pk bigint,
+ total_amount integer not null,
+ po_date date,
+ valid_till date,
+ documents bigint[] not null,
+ deleted boolean default false not null,
+ version integer default 1 not null,
+ created_at timestamp default 'now()' not null,
+ modified_at timestamp default 'now()' not null,
+ deleted_by varchar(255),
+ approval_status varchar(8) default 'APPROVED' not null,
+ tags varchar[] default '{}' not null,
+ comments jsonb default '[]' not null,
+ tenant_id varchar(255) not null,
+ products jsonb not null,
+ reference_quotation varchar(255) not null,
+ po_num varchar(255) not null,
+ tnc varchar[] not null,
+ created_by varchar(255) not null,
+ modified_by varchar(255) not null,
+ constraint ck_purchase_order_approval_status check ( approval_status in ('PENDING','APPROVED','REJECTED')),
+ constraint pk_purchase_order primary key (sys_pk)
+);
+
+create table quotation (
+ sys_pk bigint generated by default as identity not null,
+ deleted_on timestamp,
+ current_approval_level integer default 0 not null,
+ required_approval_levels integer default 0 not null,
+ vendor_sys_pk bigint,
+ total_amount integer not null,
+ quote_date date,
+ valid_till date,
+ documents bigint[] not null,
+ deleted boolean default false not null,
+ version integer default 1 not null,
+ created_at timestamp default 'now()' not null,
+ modified_at timestamp default 'now()' not null,
+ deleted_by varchar(255),
+ approval_status varchar(8) default 'APPROVED' not null,
+ tags varchar[] default '{}' not null,
+ comments jsonb default '[]' not null,
+ tenant_id varchar(255) not null,
+ products jsonb not null,
+ quote_num varchar(255) not null,
+ tnc varchar[] not null,
+ created_by varchar(255) not null,
+ modified_by varchar(255) not null,
+ constraint ck_quotation_approval_status check ( approval_status in ('PENDING','APPROVED','REJECTED')),
+ constraint pk_quotation primary key (sys_pk)
+);
+
+create table vendor (
+ sys_pk bigint generated by default as identity not null,
+ deleted_on timestamp,
+ current_approval_level integer default 0 not null,
+ required_approval_levels integer default 0 not null,
+ rating float not null,
+ deleted boolean default false not null,
+ version integer default 1 not null,
+ created_at timestamp default 'now()' not null,
+ modified_at timestamp default 'now()' not null,
+ deleted_by varchar(255),
+ approval_status varchar(8) default 'APPROVED' not null,
+ tags varchar[] default '{}' not null,
+ comments jsonb default '[]' not null,
+ tenant_id varchar(255) not null,
+ name varchar(255) not null,
+ msme varchar(255) not null,
+ gst_number varchar(255) not null,
+ address varchar(255) not null,
+ contacts jsonb not null,
+ created_by varchar(255) not null,
+ modified_by varchar(255) not null,
+ constraint ck_vendor_approval_status check ( approval_status in ('PENDING','APPROVED','REJECTED')),
+ constraint pk_vendor primary key (sys_pk)
+);
+
+-- foreign keys and indices
+create index ix_purchase_order_vendor_sys_pk on purchase_order (vendor_sys_pk);
+alter table purchase_order add constraint fk_purchase_order_vendor_sys_pk foreign key (vendor_sys_pk) references vendor (sys_pk) on delete restrict on update restrict;
+
+create index ix_quotation_vendor_sys_pk on quotation (vendor_sys_pk);
+alter table quotation add constraint fk_quotation_vendor_sys_pk foreign key (vendor_sys_pk) references vendor (sys_pk) on delete restrict on update restrict;
+
diff --git a/src/main/resources/dbmigration/model/1.2.model.xml b/src/main/resources/dbmigration/model/1.2.model.xml
new file mode 100644
index 0000000..624e77c
--- /dev/null
+++ b/src/main/resources/dbmigration/model/1.2.model.xml
@@ -0,0 +1,121 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file