2024-01-24 11:25:18 +05:30

334 lines
8.5 KiB
Kotlin

package com.restapi.domain
import com.fasterxml.jackson.core.JsonParser
import com.fasterxml.jackson.databind.DeserializationContext
import com.fasterxml.jackson.databind.JsonDeserializer
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 java.util.*
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
}
@MappedSuperclass
abstract class BaseModel : Model() {
@Id
@GeneratedValue
var sysPk: Long = 0
@SoftDelete
@DbDefault("false")
var deleted: Boolean = false
@Version
@DbDefault("1")
var version: Int = 0
@WhenCreated
@DbDefault("now()")
var createdAt: LocalDateTime = LocalDateTime.now()
@WhenModified
@DbDefault("now()")
var modifiedAt: LocalDateTime? = null
@WhoCreated
var createdBy: String = ""
@WhoModified
var modifiedBy: String? = null
var deletedOn: LocalDateTime? = null
var deletedBy: String? = null
@DbDefault("0")
var currentApprovalLevel: Int = 0
@DbDefault("0")
var requiredApprovalLevels: Int = 0
@Enumerated(EnumType.STRING)
@DbDefault("APPROVED")
var approvalStatus: ApprovalStatus = ApprovalStatus.APPROVED
@DbArray
@DbDefault("{}")
var tags: MutableList<String> = arrayListOf()
@DbJsonB
@DbDefault("[]")
var comments: MutableList<Comments> = arrayListOf()
}
@MappedSuperclass
abstract class BaseTenantModel : BaseModel() {
@TenantId
var tenantId: String = ""
}
@Entity
open class TenantModel : BaseModel() {
@Index(unique = true)
var name: String = ""
var domain: String = ""
var mobile: List<String> = emptyList()
var emails: List<String> = emptyList()
@DbJsonB
var preferences: MutableMap<String, Any> = hashMapOf()
}
enum class AuditType {
CREATE, UPDATE, DELETE, VIEW, APPROVE, REJECT
}
@Entity
@Index(columnNames = ["audit_type", "entity", "unique_identifier", "tenant_id", "created_by"])
open class AuditLog : BaseTenantModel() {
@Enumerated(EnumType.STRING)
var auditType: AuditType = AuditType.CREATE
var entity: String = ""
var uniqueIdentifier: String = ""
@DbJsonB
@Index(
definition = "create index audit_log_values_idx on audit_log using GIN (data)",
platforms = [Platform.POSTGRES]
)
var data: Map<String, Any> = hashMapOf()
@DbJsonB
@Index(
definition = "create index audit_log_changes_idx on audit_log using GIN (changes)",
platforms = [Platform.POSTGRES]
)
var changes: Map<String, Any> = hashMapOf()
}
@Entity
open class EntityModel : BaseTenantModel() {
@Index(unique = true)
@JsonDeserialize(using = SafeStringDeserializer::class)
var name: String = ""
//a kts script that will return true/false along with errors before saving
var preSaveScript: String? = ""
//a kts script that will do something ... returns void
var postSaveScript: String? = ""
//this will create extra actions/roles in keycloak
//the default actions are create, update, view, delete
@DbArray
@DbDefault("{}")
var actions: List<String> = emptyList()
//allow only these fields, if this is empty, then all fields are allowed
@DbArray
@DbDefault("{}")
var allowedFields: List<String> = emptyList()
//enforce field types, if this is present, only fields that are present is validated
@DbJsonB
@DbDefault("{}")
var allowedFieldTypes: Map<String, String> = hashMapOf()
//when an entity is saved/updated audit logs will be populated, when this is empty, all fields are logged
@DbArray
@DbDefault("{}")
var auditLogFields: List<String> = emptyList()
@DbJsonB
@DbDefault("{}")
var preferences: MutableMap<String, Any> = hashMapOf()
//if '0' then its auto saved, no approval steps are required, for further steps,
//a user needs to have ROLE_ENTITY_APPROVE_LEVEL1, ROLE_ENTITY_APPROVE_LEVEL2 roles for further approvals
@DbDefault("0")
var approvalLevels: Int = 0
}
enum class JobFrequencyType {
SPECIFIC, EVERY, CRON
}
enum class JobType {
SCRIPT, DB
}
@Entity
@Index(unique = true, name = "sql_unique_id", columnNames = ["entity_name", "sql_id", "tenant_id"])
open class SqlModel : BaseTenantModel() {
@JsonDeserialize(using = SafeStringDeserializer::class)
var sqlId: String = ""
var entityName: String = ""
@Column(columnDefinition = "text")
var sql: String = ""
}
@Entity
open class JobModel : BaseTenantModel() {
@Index(unique = true)
var jobName: String = ""
@Enumerated(EnumType.STRING)
var jobType: JobType = JobType.SCRIPT
var jobPath: String = ""
@DbArray
var tenants: List<String> = emptyList()
@Enumerated(EnumType.STRING)
var jobFrequencyType = JobFrequencyType.EVERY
var frequency: String = "1h"
}
@Entity
@Index(unique = true, name = "entity_unique_id", columnNames = ["entity_name", "unique_identifier", "tenant_id"])
open class DataModel : BaseTenantModel() {
@JsonDeserialize(using = SafeStringDeserializer::class)
var uniqueIdentifier: String = ""
@JsonDeserialize(using = SafeStringDeserializer::class)
var entityName: String = ""
@Index(definition = "create index data_jsonb_idx on data_model using GIN (data) ", platforms = [Platform.POSTGRES])
@DbJsonB
var data: MutableMap<String, Any> = hashMapOf()
}
@Entity
@Index(unique = true, name = "unique_session_id", columnNames = ["session_id"])
open class AnonSession : BaseTenantModel() {
var sessionId: String? = null
var ip: String? = null
var firstSeenAt: LocalDateTime? = null
var lastSeenAt: LocalDateTime? = null
@DbJsonB
var headerMap: Map<String, String> = hashMapOf()
}
class SafeStringDeserializer : JsonDeserializer<String>() {
private val regex = Regex("^[a-zA-Z0-9\\-_\\.]+$")
override fun deserialize(p: JsonParser, ctxt: DeserializationContext?): String {
val text = p.text
if (!regex.matches(text)) throw IllegalArgumentException()
return text
}
}
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<ContactPerson> = mutableListOf()
}
@Entity
open class PurchaseOrder :BaseTenantModel() {
@DbJsonB
var products :MutableList<POProducts> = 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<String> = arrayListOf()
@DbArray
var documents: MutableList<Long> = arrayListOf()
}
enum class UOM {
NOS, LTR, MTR, ALL
}
@Entity
open class Product :BaseTenantModel() {
var id: Int? = null
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<POProducts> = mutableListOf()
@ManyToOne
var vendor :Vendor? = null
var totalAmount :Long = 0
var reqForQuoteNum: String = ""
var quoteNum: String = ""
var quoteDate: LocalDate? = null
var validTill: LocalDate? = null
@DbArray
var tnc: List<String> = arrayListOf()
@DbArray
var documents: MutableList<Long> = arrayListOf()
}
enum class DocType{
PO, QUOTE, INVOICE, ALL
}
@Entity
open class Document :BaseTenantModel() {
var name :String = ""
@Enumerated(EnumType.STRING)
var typeOfDoc :DocType? = null
var refId: Long? = null
var description :String = ""
var url :String = ""
}
enum class RFQStatus{
DELIVERED, PO, QUOTE, CANCELLED
}
@Entity
open class ReqForQuote :BaseTenantModel() {
@DbArray
var potentialVendors :List<Long>? = null
@Enumerated(EnumType.STRING)
var status :RFQStatus? = null
// @DbArray
// var docs :List<Document>? = null
@DbJsonB
var products :List<POProducts>? = null
var reqForQuoteNum: String? = null
var openTill: LocalDate? = null
}