From f440ca89f384fd64c55b2e6ce01ee1426074cd1d Mon Sep 17 00:00:00 2001 From: arsalan Date: Wed, 17 Jan 2024 18:36:44 +0530 Subject: [PATCH] add entities and db migrations --- .idea/dataSources.xml | 18 +++ .idea/vcs.xml | 2 - api.http | 30 +++- app-sample.yaml | 1 + .../kotlin/com/restapi/AppAccessManager.kt | 1 + src/main/kotlin/com/restapi/Main.kt | 8 + src/main/kotlin/com/restapi/config/Auth.kt | 1 + .../com/restapi/controllers/Entities.kt | 14 ++ src/main/kotlin/com/restapi/domain/models.kt | 71 ++++++++- src/main/resources/dbmigration/1.2.sql | 140 ++++++++++++++++++ .../resources/dbmigration/model/1.2.model.xml | 121 +++++++++++++++ 11 files changed, 403 insertions(+), 4 deletions(-) create mode 100644 src/main/resources/dbmigration/1.2.sql create mode 100644 src/main/resources/dbmigration/model/1.2.model.xml 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