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
  PAID_DELIVERED
  CLOSED
}

enum ActionType {
  CREATED
  SUBMITTED
  APPROVED
  APPROVED_WITH_NOTE
  REJECTED
  EDITS_REQUESTED
  VENDOR_ID_REQUESTED
  VENDOR_ID_PROVIDED
  PAYMENT_SENT
  RECEIPT_CONFIRMED
  CLOSED
  REASSIGNED
  PRODUCT_PRICE_UPDATED
  MANAGER_LINE_EDIT
}

model User {
  id           String   @id @default(cuid())
  employeeId   String   @unique
  email        String   @unique
  name         String
  passwordHash String
  role         Role
  isActive     Boolean  @default(true)
  createdAt    DateTime @default(now())
  updatedAt    DateTime @updatedAt

  submittedPOs  PurchaseOrder[]  @relation("Submitter")
  actions       POAction[]
  notifications Notification[]
  consumption   ItemConsumption[]
}

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

  vessels        Vessel[]
  purchaseOrders PurchaseOrder[]
  inventory      ItemInventory[]
  consumption    ItemConsumption[]
}

model Vessel {
  id        String  @id @default(cuid())
  name      String
  imoNumber String? @unique
  isActive  Boolean @default(true)

  siteId String?
  site   Site?   @relation(fields: [siteId], references: [id])

  purchaseOrders PurchaseOrder[]
}

model Account {
  id          String  @id @default(cuid())
  code        String  @unique
  name        String
  description String?
  isActive    Boolean @default(true)

  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?
  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])
  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?
  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
  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])
}
