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: Long = 0, val productName: String = "", val unitPrice: Double = 0.0, val quantity: Double = 0.0, val billQty: Double = 0.0, val gstPct: Double = 0.0, val taxableValue: Double = 0.0, val totalValue: Double = 0.0, val description: String = "", val uom: 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 = arrayListOf() @DbJsonB @DbDefault("[]") var comments: MutableList = 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 = emptyList() var emails: List = emptyList() @DbJsonB var preferences: MutableMap = 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 = hashMapOf() @DbJsonB @Index( definition = "create index audit_log_changes_idx on audit_log using GIN (changes)", platforms = [Platform.POSTGRES] ) var changes: Map = 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 = emptyList() //allow only these fields, if this is empty, then all fields are allowed @DbArray @DbDefault("{}") var allowedFields: List = emptyList() //enforce field types, if this is present, only fields that are present is validated @DbJsonB @DbDefault("{}") var allowedFieldTypes: Map = 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 = emptyList() @DbJsonB @DbDefault("{}") var preferences: MutableMap = 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 = 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 = 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 = hashMapOf() } class SafeStringDeserializer : JsonDeserializer() { 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 } } enum class AddressType { BILLING, SHIPPING } data class ContactPerson( val id: String = UUID.randomUUID().toString(), val name: String = "", val email: String = "", val mobile: String = "" ) data class Address( val id: String = UUID.randomUUID().toString(), val type: AddressType = AddressType.BILLING, val address: String = "", val pincode: String = "" ) @Entity open class Vendor : BaseTenantModel() { fun patchValues(updatedVendor: Vendor) { this.name = updatedVendor.name this.msme = updatedVendor.msme this.gstNumber = updatedVendor.gstNumber this.address = updatedVendor.address this.rating = updatedVendor.rating this.contacts = updatedVendor.contacts this.outstanding = updatedVendor.outstanding this.asOnWhichDate = updatedVendor.asOnWhichDate this.addressList = updatedVendor.addressList } var name: String = "" var msme: String = "" var gstNumber: String = "" var address: String = "" var rating: Double = 0.0 var outstanding: Double? = 0.0 var asOnWhichDate: LocalDate? = null @DbJsonB var addressList: List
? = mutableListOf() @DbJsonB var contacts: List = mutableListOf() } @Entity open class PurchaseOrder : BaseTenantModel() { fun patchValues(updatedPo: PurchaseOrder) { this.poDate = updatedPo.poDate this.validTill = updatedPo.validTill this.tnc = updatedPo.tnc this.products = updatedPo.products this.vendor = updatedPo.vendor this.documents = updatedPo.documents this.totalAmount = updatedPo.totalAmount } @DbJsonB var products: MutableList = mutableListOf() @ManyToOne var vendor: Vendor? = null var referenceQuotation: String? = "" var totalAmount: Double = 0.0 var poNum: String = "" var poDate: LocalDate? = null var validTill: LocalDate? = null @DbArray var tnc: List? = arrayListOf() @DbArray var documents: List? = arrayListOf() } enum class UOM { KG, CFT, TON, LTR, NUMBER, MTR, BOX, CUM, PACKET, ALL, NOS; } enum class TypeOfProduct { RAW_MATERIAL } @Entity open class Product : BaseTenantModel() { fun patchValues(updatedProduct: Product) { this.name = updatedProduct.name this.description = updatedProduct.description this.hsnCode = updatedProduct.hsnCode this.uom = updatedProduct.uom this.gstPct = updatedProduct.gstPct this.code = updatedProduct.code } @Column(name = "id") var code: String? = null var name: String = "" var description: String = "" var hsnCode: String = "" @Enumerated(EnumType.STRING) var uom: UOM? = null var gstPct: Double? = 0.0 @Enumerated(EnumType.STRING) var type: TypeOfProduct? = null } @Entity open class Quotation : BaseTenantModel() { fun patchValues(updatedQuote: Quotation) { this.quoteDate = updatedQuote.quoteDate this.vendorQuoteNum = updatedQuote.vendorQuoteNum this.validTill = updatedQuote.validTill this.reqForQuoteNum = updatedQuote.reqForQuoteNum this.tnc = updatedQuote.tnc this.products = updatedQuote.products this.vendor = updatedQuote.vendor this.documents = updatedQuote.documents this.totalAmount = updatedQuote.totalAmount } @DbJsonB var products: MutableList = mutableListOf() @ManyToOne var vendor: Vendor? = null var totalAmount: Double = 0.0 var reqForQuoteNum: String? = "" var quoteNum: String = "" var vendorQuoteNum: String? = "" var quoteDate: LocalDate? = null var validTill: LocalDate? = null @DbArray var tnc: List? = arrayListOf() @DbArray var documents: List? = arrayListOf() var taxesIncluded: Boolean? = null } enum class DocType { PO, QUOTE, INVOICE, ALL } @Entity open class Document : BaseTenantModel() { var name: String = "" @Enumerated(EnumType.STRING) var typeOfDoc: DocType? = null //could be quoteNum, PoNum, InvoiceNum var refIdOfDoc: Long? = null var description: String = "" var url: String = "" var docDate: LocalDate? = null } enum class RFQStatus { DELIVERED, PO, QUOTE, CANCELLED } @Entity open class ReqForQuote : BaseTenantModel() { @DbArray var potentialVendors: List? = null @Enumerated(EnumType.STRING) var status: RFQStatus? = null @DbJsonB var products: List? = null var reqForQuoteNum: String? = null var openTill: LocalDate? = null } @Entity open class IncomingInventory : BaseTenantModel() { fun patchValues(updated: IncomingInventory) { this.date = updated.date this.vendorBillNum = updated.vendorBillNum this.vendorBillAmount = updated.vendorBillAmount this.vehicle = updated.vehicle this.products = updated.products this.vendor = updated.vendor this.loading = updated.loading this.unloading = updated.unloading this.unloadingPlantId = updated.unloadingPlantId } var mrn: String? = null var date: LocalDate? = null var vendorBillNum: String? = null var unloadingPlantId: String? = null var vendorBillAmount: Double = 0.0 var vehicle: String = "" var loading: String? = "" var unloading: String? = "" @DbJsonB var products: List? = null @ManyToOne var vendor: Vendor? = null } enum class OutMode { PERSON, VEHICLE, ALL } @Entity open class OutgoingInventory : BaseTenantModel() { fun patchValues(updated: OutgoingInventory) { this.date = updated.date this.products = updated.products this.purpose = updated.purpose this.outMode = updated.outMode this.person = updated.person this.vehicle = updated.vehicle } var mdn: String? = null var date: LocalDate? = null @DbJsonB var products: List? = null var purpose: String? = null @Enumerated(EnumType.STRING) var outMode: OutMode? = null var person: String? = null var vehicle: String? = null } enum class InvoiceStatus { PAID_FULL, PAID_SOME, PAID_NONE, ALL } @Entity open class Invoice : BaseTenantModel() { fun patchValues(updated: Invoice) { this.date = updated.date this.number = updated.number this.totalAmount = updated.totalAmount this.poNum = updated.poNum this.products = updated.products this.vendor = updated.vendor this.status = updated.status } var number: String = "" var date: LocalDate? = null var totalAmount: Double = 0.0 var poNum: String? = null @DbJsonB var products: List? = null @ManyToOne var vendor: Vendor? = null @Enumerated(EnumType.STRING) var status: InvoiceStatus? = null } @Entity open class Payment : BaseTenantModel() { fun patchValues(updated: Payment) { this.refNumber = updated.refNumber this.amount = updated.amount this.date = updated.date this.remark = updated.remark this.vendor = updated.vendor } var refNumber: String = "" var amount: Double = 0.0 var date: LocalDate? = null var remark: String? = null var amountDeducted: Double? = null var excessAmount: Double? = null @DbJsonB var invoicesAffected: MutableMap? = mutableMapOf() @ManyToOne var vendor: Vendor? = null } data class FR(val renewal: String, val date: LocalDate) @Entity open class Fleet : BaseTenantModel() { fun patchValues(updated: Fleet) { this.name = updated.name this.type = updated.type this.regNumber = updated.regNumber this.model = updated.model this.make = updated.make this.driver = updated.driver this.driverContact = updated.driverContact this.mileage = updated.mileage this.cost = updated.cost this.insuranceRenewalDate = updated.insuranceRenewalDate this.pollutionRenewalDate = updated.pollutionRenewalDate this.fitnessRenewalDate = updated.fitnessRenewalDate this.renewals = updated.renewals this.regDate = updated.regDate } var name: String = "" var type: String = "" var regNumber: String = "" var regDate: LocalDate? = null var model: String = "" var make: String = "" var driver: String = "" var driverContact: String = "" var mileage: Double = 0.0 var cost: Double = 0.0 var insuranceRenewalDate: LocalDate? = null var pollutionRenewalDate: LocalDate? = null var fitnessRenewalDate: LocalDate? = null @DbJsonB var renewals: List? = null } @Entity open class FleetType : BaseTenantModel() { fun patchValues(updated: FleetType) { this.name = updated.name this.personIncharge = updated.personIncharge } var name: String = "" var personIncharge: String = "" } @Entity open class Vehicle : BaseTenantModel() { fun patchValues(updated: Vehicle) { this.name = updated.name } var name: String = "" } @Entity open class Renewal : BaseTenantModel() { fun patchValues(updated: Renewal) { this.name = updated.name } var name: String = "" } @Entity open class Reminder : BaseTenantModel() { fun patchValues(updated: Reminder) { this.type = updated.type this.nextRenewalDate = updated.nextRenewalDate this.lastRenewalDate = updated.lastRenewalDate this.frequency = updated.frequency this.documents = updated.documents } var type: String = "Other" var nextRenewalDate: LocalDate? = null var lastRenewalDate: LocalDate? = null var amount: Double = 0.0 var frequency: Int = 1 @DbArray var documents: List? = arrayListOf() @ManyToOne var fleet: Fleet? = null } @Entity open class ReminderLog : BaseTenantModel() { fun patchValues(updated: ReminderLog) { this.fleet = updated.fleet this.reminderDate = updated.reminderDate this.reminderType = updated.reminderType this.actedUpon = updated.actedUpon this.documents = updated.documents this.amount = updated.amount } @ManyToOne var reminder: Reminder? = null var reminderType: String = "Other" var reminderDate: LocalDate? = null @ManyToOne var fleet: Fleet? = null var actedUpon: Boolean = false var amount: Double = 0.0 @DbArray var documents: List? = null } @Entity @Index(name = "plantid_idx", columnNames = ["plant_id"], unique = true) open class Plant : BaseModel() { fun patch(p: Plant) { this.plantName = p.plantName this.prefixes?.apply { this.clear() this.putAll(p.prefixes ?: emptyMap()) } this.save() } var plantId: String = "" var plantName: String = "" @DbJsonB var prefixes: MutableMap? = mutableMapOf() } class RefreshHistory { var oldAt: String = "" var oldExpiryAt: String = "" var newAt: String = "" var newExpiryAt: String = "" var createdAt: String = "" } @Entity open class AuthTokenCache : BaseModel() { @Column(columnDefinition = "text") var authToken: String = "" var issuedAt: LocalDateTime = LocalDateTime.now() var expiresAt: LocalDateTime = LocalDateTime.now() var refreshExpiresAt: LocalDateTime = LocalDateTime.now() @Column(columnDefinition = "text") var refreshToken: String = "" var userId: String = "" var expired: Boolean = false var loggedOut: Boolean = false @DbJsonB var refreshHistory: MutableList? = arrayListOf() }