generator client { provider = "prisma-client-js" } datasource db { provider = "postgresql" url = env("DATABASE_URL") } enum Role { TECHNICAL MANNING ACCOUNTS MANAGER SUPERUSER AUDITOR ADMIN } enum POStatus { DRAFT SUBMITTED MGR_REVIEW VENDOR_ID_PENDING EDITS_REQUESTED REJECTED MGR_APPROVED SENT_FOR_PAYMENT PARTIALLY_PAID PAID_DELIVERED PARTIALLY_CLOSED CLOSED } enum ActionType { CREATED SUBMITTED APPROVED APPROVED_WITH_NOTE REJECTED EDITS_REQUESTED VENDOR_ID_REQUESTED VENDOR_ID_PROVIDED PAYMENT_SENT PARTIAL_PAYMENT_CONFIRMED RECEIPT_CONFIRMED PARTIAL_RECEIPT_CONFIRMED CLOSED REASSIGNED PRODUCT_PRICE_UPDATED MANAGER_LINE_EDIT } enum RequestStatus { PENDING APPROVED DENIED } model User { id String @id @default(cuid()) employeeId String @unique email String @unique name String passwordHash String? role Role isActive Boolean @default(true) signatureKey String? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt submittedPOs PurchaseOrder[] @relation("Submitter") actions POAction[] notifications Notification[] consumption ItemConsumption[] superUserRequests SuperUserRequest[] @relation("Requester") resolvedRequests SuperUserRequest[] @relation("RequestResolver") } model SuperUserRequest { id String @id @default(cuid()) userId String user User @relation("Requester", fields: [userId], references: [id]) reason String? status RequestStatus @default(PENDING) createdAt DateTime @default(now()) resolvedAt DateTime? resolvedById String? resolvedBy User? @relation("RequestResolver", fields: [resolvedById], references: [id]) } model Site { id String @id @default(cuid()) name String code String @unique address String? latitude Float? longitude Float? isActive Boolean @default(true) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt purchaseOrders PurchaseOrder[] inventory ItemInventory[] consumption ItemConsumption[] } model Vessel { id String @id @default(cuid()) name String code String @unique isActive Boolean @default(true) purchaseOrders PurchaseOrder[] } model Company { id String @id @default(cuid()) name String gstNumber String? address String? telephone String? mobile String? email String? invoiceEmail String? invoiceAddress String? isActive Boolean @default(true) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt purchaseOrders PurchaseOrder[] } model Account { id String @id @default(cuid()) code String @unique name String description String? isActive Boolean @default(true) parentId String? parent Account? @relation("AccountHierarchy", fields: [parentId], references: [id]) children Account[] @relation("AccountHierarchy") purchaseOrders PurchaseOrder[] lineItems POLineItem[] } model VendorContact { id String @id @default(cuid()) name String role String? mobile String? email String? isPrimary Boolean @default(false) createdAt DateTime @default(now()) vendorId String vendor Vendor @relation(fields: [vendorId], references: [id], onDelete: Cascade) } model Vendor { id String @id @default(cuid()) name String vendorId String? @unique address String? pincode String? gstin String? latitude Float? longitude Float? isVerified Boolean @default(false) isActive Boolean @default(true) createdAt DateTime @default(now()) contacts VendorContact[] purchaseOrders PurchaseOrder[] products Product[] @relation("ProductLastVendor") vendorPrices ProductVendorPrice[] } model Product { id String @id @default(cuid()) code String @unique name String description String? lastPrice Decimal? @db.Decimal(12, 2) lastVendorId String? lastVendor Vendor? @relation("ProductLastVendor", fields: [lastVendorId], references: [id]) isActive Boolean @default(true) updatedAt DateTime @updatedAt createdAt DateTime @default(now()) lineItems POLineItem[] vendorPrices ProductVendorPrice[] inventory ItemInventory[] consumption ItemConsumption[] } model ProductVendorPrice { id String @id @default(cuid()) price Decimal @db.Decimal(12, 2) updatedAt DateTime @updatedAt productId String product Product @relation(fields: [productId], references: [id], onDelete: Cascade) vendorId String vendor Vendor @relation(fields: [vendorId], references: [id]) @@unique([productId, vendorId]) } model ItemInventory { id String @id @default(cuid()) quantity Decimal @db.Decimal(10, 3) updatedAt DateTime @updatedAt productId String product Product @relation(fields: [productId], references: [id]) siteId String site Site @relation(fields: [siteId], references: [id]) @@unique([productId, siteId]) } model ItemConsumption { id String @id @default(cuid()) date DateTime @db.Date quantity Decimal @db.Decimal(10, 3) note String? productId String product Product @relation(fields: [productId], references: [id]) siteId String site Site @relation(fields: [siteId], references: [id]) recordedById String recordedBy User @relation(fields: [recordedById], references: [id]) @@unique([productId, siteId, date]) } model PurchaseOrder { id String @id @default(cuid()) poNumber String @unique title String status POStatus @default(DRAFT) totalAmount Decimal @db.Decimal(12, 2) currency String @default("INR") dateRequired DateTime? projectCode String? managerNote String? paymentRef String? paidAmount Decimal? @db.Decimal(12, 2) piQuotationNo String? piQuotationDate DateTime? requisitionNo String? requisitionDate DateTime? placeOfDelivery String? tcDelivery String? tcDispatch String? tcInspection String? tcTransitInsurance String? tcPaymentTerms String? tcOthers String? submittedAt DateTime? approvedAt DateTime? paidAt DateTime? closedAt DateTime? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt submitterId String submitter User @relation("Submitter", fields: [submitterId], references: [id]) vesselId String vessel Vessel @relation(fields: [vesselId], references: [id]) accountId String account Account @relation(fields: [accountId], references: [id]) companyId String? company Company? @relation(fields: [companyId], references: [id]) vendorId String? vendor Vendor? @relation(fields: [vendorId], references: [id]) siteId String? site Site? @relation(fields: [siteId], references: [id]) lineItems POLineItem[] documents PODocument[] actions POAction[] receipt Receipt? notifications Notification[] } model POLineItem { id String @id @default(cuid()) name String description String? quantity Decimal @db.Decimal(10, 3) unit String unitPrice Decimal @db.Decimal(12, 2) totalPrice Decimal @db.Decimal(12, 2) gstRate Decimal @default(0.18) @db.Decimal(5, 4) sortOrder Int @default(0) size String? deliveredQuantity Decimal? @db.Decimal(10, 3) productId String? product Product? @relation(fields: [productId], references: [id]) accountId String? account Account? @relation(fields: [accountId], references: [id]) poId String po PurchaseOrder @relation(fields: [poId], references: [id], onDelete: Cascade) } model PODocument { id String @id @default(cuid()) fileName String fileSize Int mimeType String storageKey String uploadedAt DateTime @default(now()) poId String po PurchaseOrder @relation(fields: [poId], references: [id], onDelete: Cascade) } model POAction { id String @id @default(cuid()) actionType ActionType note String? metadata Json? createdAt DateTime @default(now()) poId String po PurchaseOrder @relation(fields: [poId], references: [id]) actorId String actor User @relation(fields: [actorId], references: [id]) } model Receipt { id String @id @default(cuid()) storageKey String fileName String notes String? confirmedAt DateTime @default(now()) poId String @unique po PurchaseOrder @relation(fields: [poId], references: [id]) } model Notification { id String @id @default(cuid()) subject String body String link String? isRead Boolean @default(false) sentAt DateTime @default(now()) status String @default("sent") poId String? po PurchaseOrder? @relation(fields: [poId], references: [id]) userId String user User @relation(fields: [userId], references: [id]) }