generator client {
  provider      = "prisma-client-js"
  binaryTargets = ["native", "darwin-arm64", "debian-openssl-3.0.x", "linux-musl-openssl-3.0.x"]
}

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

enum AdjustmentReasonCategory {
  SHRINKAGE
  DAMAGE
  REGRADE
  ADJUSTMENT
}

model Role {
  id        BigInt   @id @default(autoincrement())
  code      String   @unique @db.VarChar(50)
  name      String   @db.VarChar(100)
  createdAt DateTime @default(now()) @map("created_at")
  updatedAt DateTime @updatedAt @map("updated_at")
  users     User[]

  @@map("roles")
}

model User {
  id                      BigInt                   @id @default(autoincrement())
  roleId                  BigInt                   @map("role_id")
  role                    Role                     @relation(fields: [roleId], references: [id], onDelete: Restrict)
  name                    String                   @db.VarChar(150)
  username                String?                  @unique @db.VarChar(50)
  email                   String?                  @unique @db.VarChar(150)
  emailVerifiedAt         DateTime?                @map("email_verified_at")
  phone                   String?                  @db.VarChar(50)
  passwordHash            String?                  @map("password_hash") @db.VarChar(255)
  status                  String                   @default("ACTIVE") @db.VarChar(20)
  createdAt               DateTime                 @default(now()) @map("created_at")
  updatedAt               DateTime                 @updatedAt @map("updated_at")
  purchases               Purchase[]
  receipts                Receipt[]
  createdTransformations  LotTransformation[]      @relation("TransformationCreatedBy")
  createdStockAdjustments StockAdjustment[]        @relation("StockAdjustmentCreatedBy")
  createdWashings         LotWashing[]             @relation("WashingCreatedBy")
  completedWashings       LotWashing[]             @relation("WashingCompletedBy")
  createdConsignments     Consignment[]            @relation("ConsignmentCreatedBy")
  createdRegularSales     RegularSale[]            @relation("RegularSaleCreatedBy")
  createdJitSales         JitSale[]                @relation("JitSaleCreatedBy")
  createdFundRequests     FundRequest[]            @relation("FundRequestCreatedBy")
  passwordResetTokens     PasswordResetToken[]
  emailVerificationTokens EmailVerificationToken[]
  auditTrails             AuditTrail[]

  @@map("users")
}

model AuditTrail {
  id         BigInt   @id @default(autoincrement())
  userId     BigInt?  @map("user_id")
  user       User?    @relation(fields: [userId], references: [id], onDelete: SetNull)
  action     String   @db.VarChar(100)
  entityType String   @map("entity_type") @db.VarChar(100)
  entityId   String?  @map("entity_id") @db.VarChar(100)
  method     String   @db.VarChar(10)
  pathname   String   @db.VarChar(255)
  statusCode Int      @map("status_code")
  summary    String?  @db.VarChar(255)
  metadata   Json?
  occurredAt DateTime @default(now()) @map("occurred_at")

  @@index([action, occurredAt])
  @@index([entityType, occurredAt])
  @@index([userId, occurredAt])
  @@map("audit_trails")
}

model PasswordResetToken {
  id        BigInt    @id @default(autoincrement())
  userId    BigInt    @map("user_id")
  user      User      @relation(fields: [userId], references: [id], onDelete: Cascade)
  tokenHash String    @unique @map("token_hash") @db.VarChar(255)
  purpose   String    @default("RESET_PASSWORD") @db.VarChar(50)
  expiresAt DateTime  @map("expires_at")
  usedAt    DateTime? @map("used_at")
  createdAt DateTime  @default(now()) @map("created_at")

  @@map("password_reset_tokens")
}

model EmailVerificationToken {
  id        BigInt    @id @default(autoincrement())
  userId    BigInt    @map("user_id")
  user      User      @relation(fields: [userId], references: [id], onDelete: Cascade)
  tokenHash String    @unique @map("token_hash") @db.VarChar(255)
  expiresAt DateTime  @map("expires_at")
  usedAt    DateTime? @map("used_at")
  createdAt DateTime  @default(now()) @map("created_at")

  @@map("email_verification_tokens")
}

model Buyer {
  id                  BigInt               @id @default(autoincrement())
  code                String               @unique @db.VarChar(50)
  name                String               @db.VarChar(150)
  phone               String?              @db.VarChar(50)
  email               String?              @db.VarChar(150)
  bankName            String?              @map("bank_name") @db.VarChar(100)
  bankAccountNumber   String?              @map("bank_account_number") @db.VarChar(100)
  address             String?
  status              String               @default("ACTIVE") @db.VarChar(20)
  createdAt           DateTime             @default(now()) @map("created_at")
  updatedAt           DateTime             @updatedAt @map("updated_at")
  contactPeople       BuyerContactPerson[]
  consignmentsAsBuyer Consignment[]        @relation("ConsignmentBuyer")
  regularSalesAsBuyer RegularSale[]        @relation("RegularSaleBuyer")
  jitSalesAsBuyer     JitSale[]            @relation("JitSaleBuyer")

  @@map("buyers")
}

model BuyerContactPerson {
  id          BigInt   @id @default(autoincrement())
  buyerId     BigInt   @map("buyer_id")
  buyer       Buyer    @relation(fields: [buyerId], references: [id], onDelete: Cascade)
  name        String   @db.VarChar(150)
  mobilePhone String?  @map("mobile_phone") @db.VarChar(50)
  email       String?  @db.VarChar(150)
  createdAt   DateTime @default(now()) @map("created_at")
  updatedAt   DateTime @updatedAt @map("updated_at")

  @@map("buyer_contact_people")
}

model Employee {
  id                BigInt     @id @default(autoincrement())
  code              String     @unique @db.VarChar(20)
  name              String     @db.VarChar(150)
  email             String?    @db.VarChar(150)
  mobile            String?    @db.VarChar(50)
  position          String     @db.VarChar(150)
  address           String?
  status            String     @default("ACTIVE") @db.VarChar(20)
  createdAt         DateTime   @default(now()) @map("created_at")
  updatedAt         DateTime   @updatedAt @map("updated_at")
  receivedPurchases Purchase[]

  @@map("employees")
}

model Courier {
  id           BigInt        @id @default(autoincrement())
  code         String        @unique @db.VarChar(20)
  name         String        @db.VarChar(150)
  address      String?
  phone        String?       @db.VarChar(50)
  website      String?       @db.VarChar(255)
  email        String?       @db.VarChar(150)
  status       String        @default("ACTIVE") @db.VarChar(20)
  createdAt    DateTime      @default(now()) @map("created_at")
  updatedAt    DateTime      @updatedAt @map("updated_at")
  purchases    Purchase[]
  regularSales RegularSale[]
  jitSales     JitSale[]

  @@map("couriers")
}

model WashingPlace {
  id            BigInt                      @id @default(autoincrement())
  code          String                      @unique @db.VarChar(20)
  name          String                      @db.VarChar(150)
  address       String?
  phone         String?                     @db.VarChar(50)
  website       String?                     @db.VarChar(255)
  email         String?                     @db.VarChar(150)
  status        String                      @default("ACTIVE") @db.VarChar(20)
  createdAt     DateTime                    @default(now()) @map("created_at")
  updatedAt     DateTime                    @updatedAt @map("updated_at")
  contactPeople WashingPlaceContactPerson[]
  washings      LotWashing[]

  @@map("washing_places")
}

model WashingPlaceContactPerson {
  id             BigInt       @id @default(autoincrement())
  washingPlaceId BigInt       @map("washing_place_id")
  washingPlace   WashingPlace @relation(fields: [washingPlaceId], references: [id], onDelete: Cascade)
  name           String       @db.VarChar(150)
  mobilePhone    String?      @map("mobile_phone") @db.VarChar(50)
  email          String?      @db.VarChar(150)
  createdAt      DateTime     @default(now()) @map("created_at")
  updatedAt      DateTime     @updatedAt @map("updated_at")

  @@map("washing_place_contact_people")
}

model Grade {
  id                 BigInt                   @id @default(autoincrement())
  code               String                   @unique @db.VarChar(20)
  legacyCode         String?                  @unique @map("legacy_code") @db.VarChar(20)
  isMangkok          Boolean                  @default(false) @map("is_mangkok")
  name               String                   @db.VarChar(150)
  description        String?
  status             String                   @default("ACTIVE") @db.VarChar(20)
  createdAt          DateTime                 @default(now()) @map("created_at")
  updatedAt          DateTime                 @updatedAt @map("updated_at")
  buyPriceStandards  GradeBuyPriceStandard[]
  sellPriceStandards GradeSellPriceStandard[]
  purchaseLines      PurchaseLine[]
  receiptLines       ReceiptLine[]
  lots               InventoryLot[]
  jitSaleLines       JitSaleLine[]

  @@map("grades")
}

model GradeBuyPriceStandard {
  id        BigInt    @id @default(autoincrement())
  gradeId   BigInt    @map("grade_id")
  grade     Grade     @relation(fields: [gradeId], references: [id], onDelete: Cascade)
  startDate DateTime  @map("start_date") @db.Date
  endDate   DateTime? @map("end_date") @db.Date
  minPrice  Decimal   @map("min_price") @db.Decimal(18, 2)
  maxPrice  Decimal   @map("max_price") @db.Decimal(18, 2)
  notes     String?
  createdAt DateTime  @default(now()) @map("created_at")
  updatedAt DateTime  @updatedAt @map("updated_at")

  @@map("grade_buy_price_standards")
}

model GradeSellPriceStandard {
  id        BigInt    @id @default(autoincrement())
  gradeId   BigInt    @map("grade_id")
  grade     Grade     @relation(fields: [gradeId], references: [id], onDelete: Cascade)
  startDate DateTime  @map("start_date") @db.Date
  endDate   DateTime? @map("end_date") @db.Date
  minPrice  Decimal   @map("min_price") @db.Decimal(18, 2)
  maxPrice  Decimal   @map("max_price") @db.Decimal(18, 2)
  notes     String?
  createdAt DateTime  @default(now()) @map("created_at")
  updatedAt DateTime  @updatedAt @map("updated_at")

  @@map("grade_sell_price_standards")
}

model Warehouse {
  id            BigInt              @id @default(autoincrement())
  code          String              @unique @db.VarChar(50)
  name          String              @db.VarChar(100)
  address       String?
  status        String              @default("ACTIVE") @db.VarChar(20)
  createdAt     DateTime            @default(now()) @map("created_at")
  updatedAt     DateTime            @updatedAt @map("updated_at")
  locations     WarehouseLocation[]
  receiptLines  ReceiptLine[]
  lots          InventoryLot[]
  purchaseLines PurchaseLine[]

  @@map("warehouses")
}

model Unit {
  id            BigInt         @id @default(autoincrement())
  code          String         @unique @db.VarChar(20)
  name          String         @db.VarChar(50)
  createdAt     DateTime       @default(now()) @map("created_at")
  updatedAt     DateTime       @updatedAt @map("updated_at")
  purchaseLines PurchaseLine[]
  receiptLines  ReceiptLine[]
  lots          InventoryLot[]

  @@map("units")
}

model Currency {
  id          BigInt   @id @default(autoincrement())
  code        String   @unique @db.VarChar(10)
  name        String   @db.VarChar(100)
  description String?
  status      String   @default("ACTIVE") @db.VarChar(20)
  createdAt   DateTime @default(now()) @map("created_at")
  updatedAt   DateTime @updatedAt @map("updated_at")

  @@map("currencies")
}

model Bank {
  id                  BigInt               @id @default(autoincrement())
  code                String               @unique @db.VarChar(3)
  name                String               @unique @db.VarChar(150)
  address             String?
  status              String               @default("ACTIVE") @db.VarChar(20)
  createdAt           DateTime             @default(now()) @map("created_at")
  updatedAt           DateTime             @updatedAt @map("updated_at")
  agentBankAccounts   AgentBankAccount[]
  salesBankAccounts   SalesBankAccount[]
  companyBankAccounts CompanyBankAccount[]

  @@map("banks")
}

model ProfitShareScheme {
  id           BigInt        @id @default(autoincrement())
  code         String        @unique @db.VarChar(20)
  name         String        @db.VarChar(150)
  shareAgent   Decimal       @map("share_agent") @db.Decimal(5, 2)
  shareCompany Decimal       @map("share_company") @db.Decimal(5, 2)
  status       String        @default("ACTIVE") @db.VarChar(20)
  createdAt    DateTime      @default(now()) @map("created_at")
  updatedAt    DateTime      @updatedAt @map("updated_at")
  agents       Agent[]
  purchases    Purchase[]
  jitSaleLines JitSaleLine[]

  @@map("profit_share_schemes")
}

model Agent {
  id                  BigInt                 @id @default(autoincrement())
  code                String                 @unique @db.VarChar(20)
  name                String                 @db.VarChar(150)
  identityType        String                 @map("identity_type") @db.VarChar(20)
  identityNumber      String                 @map("identity_number") @db.VarChar(100)
  mobilePhone         String?                @map("mobile_phone") @db.VarChar(50)
  email               String?                @db.VarChar(150)
  address             String?
  notes               String?
  joinDate            DateTime               @map("join_date") @db.Date
  profitShareSchemeId BigInt                 @map("profit_share_scheme_id")
  profitShareScheme   ProfitShareScheme      @relation(fields: [profitShareSchemeId], references: [id], onDelete: Restrict)
  currentBalance      Decimal                @default(0) @map("current_balance") @db.Decimal(18, 2)
  capitalBalance      Decimal                @default(0) @map("capital_balance") @db.Decimal(18, 2)
  createdAt           DateTime               @default(now()) @map("created_at")
  updatedAt           DateTime               @updatedAt @map("updated_at")
  bankAccounts        AgentBankAccount[]
  balanceMutations    AgentBalanceMutation[]
  fundRequests        FundRequest[]
  purchases           Purchase[]             @relation("PurchaseAgent")
  buyoutPurchases     Purchase[]             @relation("PurchaseBuyoutSourceAgent")
  jitSaleLines        JitSaleLine[]

  @@unique([identityType, identityNumber])
  @@map("agents")
}

model AgentBankAccount {
  id            BigInt        @id @default(autoincrement())
  agentId       BigInt        @map("agent_id")
  agent         Agent         @relation(fields: [agentId], references: [id], onDelete: Cascade)
  bankId        BigInt        @map("bank_id")
  bank          Bank          @relation(fields: [bankId], references: [id], onDelete: Restrict)
  accountNumber String        @map("account_number") @db.VarChar(100)
  createdAt     DateTime      @default(now()) @map("created_at")
  updatedAt     DateTime      @updatedAt @map("updated_at")
  fundRequests  FundRequest[]

  @@unique([agentId, bankId, accountNumber])
  @@map("agent_bank_accounts")
}

model AgentBalanceMutation {
  id            BigInt    @id @default(autoincrement())
  agentId       BigInt    @map("agent_id")
  agent         Agent     @relation(fields: [agentId], references: [id], onDelete: Cascade)
  balanceType   String    @map("balance_type") @db.VarChar(30)
  direction     String    @db.VarChar(10)
  source        String    @db.VarChar(50)
  amount        Decimal   @db.Decimal(18, 2)
  balanceAfter  Decimal   @map("balance_after") @db.Decimal(18, 2)
  occurredAt    DateTime  @default(now()) @map("occurred_at")
  effectiveDate DateTime? @map("effective_date") @db.Date
  referenceType String?   @map("reference_type") @db.VarChar(50)
  referenceId   String?   @map("reference_id") @db.VarChar(100)
  referenceNo   String?   @map("reference_no") @db.VarChar(100)
  notes         String?
  metadata      Json?

  @@index([agentId, occurredAt])
  @@index([agentId, balanceType, occurredAt])
  @@map("agent_balance_mutations")
}

model FundRequest {
  id                           BigInt              @id @default(autoincrement())
  requestNo                    String              @unique @map("request_no") @db.VarChar(50)
  referenceNo                  String              @map("reference_no") @db.VarChar(100)
  transferType                 String              @map("transfer_type") @db.VarChar(30)
  agentId                      BigInt              @map("agent_id")
  agent                        Agent               @relation(fields: [agentId], references: [id], onDelete: Restrict)
  agentBankAccountId           BigInt              @map("agent_bank_account_id")
  agentBankAccount             AgentBankAccount    @relation(fields: [agentBankAccountId], references: [id], onDelete: Restrict)
  companyBankAccountId         BigInt?             @map("company_bank_account_id")
  companyBankAccount           CompanyBankAccount? @relation(fields: [companyBankAccountId], references: [id], onDelete: Restrict)
  agentBankNameSnapshot        String              @map("agent_bank_name_snapshot") @db.VarChar(150)
  agentAccountNumberSnapshot   String              @map("agent_account_number_snapshot") @db.VarChar(100)
  companyBankNameSnapshot      String              @map("company_bank_name_snapshot") @db.VarChar(150)
  companyAccountNumberSnapshot String              @map("company_account_number_snapshot") @db.VarChar(100)
  amount                       Decimal             @db.Decimal(18, 2)
  currencyCode                 String              @default("IDR") @map("currency_code") @db.VarChar(10)
  transferredAt                DateTime            @map("transferred_at")
  transferProofFileUrl         String?             @map("transfer_proof_file_url") @db.VarChar(255)
  status                       String              @default("SUBMITTED") @db.VarChar(20)
  createdById                  BigInt              @map("created_by")
  createdBy                    User                @relation("FundRequestCreatedBy", fields: [createdById], references: [id], onDelete: Restrict)
  createdAt                    DateTime            @default(now()) @map("created_at")
  updatedAt                    DateTime            @updatedAt @map("updated_at")

  @@index([agentId, transferredAt])
  @@index([transferType, transferredAt])
  @@map("fund_requests")
}

model Sales {
  id                  BigInt                    @id @default(autoincrement())
  code                String                    @unique @db.VarChar(20)
  name                String                    @db.VarChar(150)
  identityType        String                    @map("identity_type") @db.VarChar(20)
  identityNumber      String                    @map("identity_number") @db.VarChar(100)
  mobilePhone         String?                   @map("mobile_phone") @db.VarChar(50)
  email               String?                   @db.VarChar(150)
  address             String?
  notes               String?
  joinDate            DateTime                  @map("join_date") @db.Date
  commissionBalance   Decimal                   @default(0) @map("commission_balance") @db.Decimal(18, 2)
  createdAt           DateTime                  @default(now()) @map("created_at")
  updatedAt           DateTime                  @updatedAt @map("updated_at")
  bankAccounts        SalesBankAccount[]
  consignments        Consignment[]             @relation("ConsignmentSales")
  commissionMutations SalesCommissionMutation[]

  @@unique([identityType, identityNumber])
  @@map("sales")
}

model SalesCommissionMutation {
  id            BigInt    @id @default(autoincrement())
  salesId       BigInt    @map("sales_id")
  sales         Sales     @relation(fields: [salesId], references: [id], onDelete: Cascade)
  source        String    @db.VarChar(50)
  direction     String    @db.VarChar(10)
  amount        Decimal   @db.Decimal(18, 2)
  balanceAfter  Decimal   @map("balance_after") @db.Decimal(18, 2)
  occurredAt    DateTime  @default(now()) @map("occurred_at")
  effectiveDate DateTime? @map("effective_date") @db.Date
  referenceType String?   @map("reference_type") @db.VarChar(50)
  referenceId   String?   @map("reference_id") @db.VarChar(100)
  referenceNo   String?   @map("reference_no") @db.VarChar(100)
  notes         String?
  metadata      Json?

  @@index([salesId, occurredAt])
  @@map("sales_commission_mutations")
}

model SalesBankAccount {
  id            BigInt   @id @default(autoincrement())
  salesId       BigInt   @map("sales_id")
  sales         Sales    @relation(fields: [salesId], references: [id], onDelete: Cascade)
  bankId        BigInt   @map("bank_id")
  bank          Bank     @relation(fields: [bankId], references: [id], onDelete: Restrict)
  accountNumber String   @map("account_number") @db.VarChar(100)
  createdAt     DateTime @default(now()) @map("created_at")
  updatedAt     DateTime @updatedAt @map("updated_at")

  @@unique([salesId, bankId, accountNumber])
  @@map("sales_bank_accounts")
}

model WarehouseLocation {
  id            BigInt         @id @default(autoincrement())
  warehouseId   BigInt         @map("warehouse_id")
  warehouse     Warehouse      @relation(fields: [warehouseId], references: [id], onDelete: Restrict)
  code          String         @db.VarChar(50)
  name          String         @db.VarChar(100)
  locationType  String?        @map("location_type") @db.VarChar(50)
  status        String         @default("ACTIVE") @db.VarChar(20)
  createdAt     DateTime       @default(now()) @map("created_at")
  updatedAt     DateTime       @updatedAt @map("updated_at")
  receiptLines  ReceiptLine[]
  lots          InventoryLot[]
  purchaseLines PurchaseLine[]

  @@unique([warehouseId, code])
  @@map("warehouse_locations")
}

model AdjustmentReason {
  id               BigInt            @id @default(autoincrement())
  code             String            @unique @db.VarChar(50)
  name             String            @db.VarChar(100)
  description      String?           @db.VarChar(255)
  category         AdjustmentReasonCategory
  status           String            @default("ACTIVE") @db.VarChar(20)
  createdAt        DateTime          @default(now()) @map("created_at")
  updatedAt        DateTime          @updatedAt @map("updated_at")
  stockAdjustments StockAdjustment[]

  @@map("adjustment_reasons")
}

model Purchase {
  id                          BigInt                      @id @default(autoincrement())
  purchaseNo                  String                      @unique @map("purchase_no") @db.VarChar(50)
  purchaseType                String                      @default("REGULAR") @map("purchase_type") @db.VarChar(30)
  purchaseDate                DateTime                    @map("purchase_date") @db.Date
  supplierInvoiceNo           String?                     @map("supplier_invoice_no") @db.VarChar(100)
  agentId                     BigInt?                     @map("agent_id")
  agent                       Agent?                      @relation("PurchaseAgent", fields: [agentId], references: [id], onDelete: Restrict)
  buyoutSourceAgentId         BigInt?                     @map("buyout_source_agent_id")
  buyoutSourceAgent           Agent?                      @relation("PurchaseBuyoutSourceAgent", fields: [buyoutSourceAgentId], references: [id], onDelete: Restrict)
  profitShareSchemeId         BigInt?                     @map("profit_share_scheme_id")
  profitShareScheme           ProfitShareScheme?          @relation(fields: [profitShareSchemeId], references: [id], onDelete: Restrict)
  courierId                   BigInt?                     @map("courier_id")
  courier                     Courier?                    @relation(fields: [courierId], references: [id], onDelete: Restrict)
  receivedByEmployeeId        BigInt?                     @map("received_by_employee_id")
  receivedByEmployee          Employee?                   @relation(fields: [receivedByEmployeeId], references: [id], onDelete: Restrict)
  receivedAt                  DateTime?                   @map("received_at")
  moistureBuyPercent          Decimal?                    @map("moisture_buy_percent") @db.Decimal(7, 2)
  moistureReceivedPercent     Decimal?                    @map("moisture_received_percent") @db.Decimal(7, 2)
  aboveAverageRatioPercent    Decimal?                    @map("above_average_ratio_percent") @db.Decimal(7, 2)
  mkSharePercent              Decimal?                    @map("mk_share_percent") @db.Decimal(7, 2)
  nonMkSharePercent           Decimal?                    @map("non_mk_share_percent") @db.Decimal(7, 2)
  shippingCost                Decimal?                    @map("shipping_cost") @db.Decimal(18, 2)
  incomingOperationalCost     Decimal?                    @map("incoming_operational_cost") @db.Decimal(18, 2)
  afterArrivalOperationalCost Decimal?                    @map("after_arrival_operational_cost") @db.Decimal(18, 2)
  status                      String                      @default("DRAFT") @db.VarChar(20)
  notes                       String?
  createdById                 BigInt                      @map("created_by")
  createdBy                   User                        @relation(fields: [createdById], references: [id], onDelete: Restrict)
  createdAt                   DateTime                    @default(now()) @map("created_at")
  updatedAt                   DateTime                    @updatedAt @map("updated_at")
  lines                       PurchaseLine[]
  receipts                    Receipt[]
  lots                        InventoryLot[]
  analysis                    PurchaseAnalysis?
  lotAllocations              LotPurchaseAllocation[]
  realizationEntries          PurchaseRealizationEntry[]
  realizationSummary          PurchaseRealizationSummary?

  @@map("purchases")
}

model PurchaseLine {
  id                         BigInt                  @id @default(autoincrement())
  purchaseId                 BigInt                  @map("purchase_id")
  purchase                   Purchase                @relation(fields: [purchaseId], references: [id], onDelete: Cascade)
  gradeId                    BigInt?                 @map("grade_id")
  grade                      Grade?                  @relation(fields: [gradeId], references: [id], onDelete: Restrict)
  sourceLotId                BigInt?                 @map("source_lot_id")
  sourceLot                  InventoryLot?           @relation("OfficeBuyoutSourceLot", fields: [sourceLotId], references: [id], onDelete: Restrict)
  qtyOrdered                 Decimal                 @map("qty_ordered") @db.Decimal(18, 3)
  purchaseMoisturePercent    Decimal?                @map("purchase_moisture_percent") @db.Decimal(7, 2)
  qtyReceived                Decimal                 @default(0) @map("qty_received") @db.Decimal(18, 3)
  qtyAccepted                Decimal                 @default(0) @map("qty_accepted") @db.Decimal(18, 3)
  qtyRejected                Decimal                 @map("qty_rejected") @db.Decimal(18, 3)
  moistureReceivedPercent    Decimal?                @map("moisture_received_percent") @db.Decimal(7, 2)
  unitId                     BigInt                  @map("unit_id")
  unit                       Unit                    @relation(fields: [unitId], references: [id], onDelete: Restrict)
  unitPrice                  Decimal                 @map("unit_price") @db.Decimal(18, 2)
  buyoutMalUnitPriceSnapshot Decimal?                @map("buyout_mal_unit_price_snapshot") @db.Decimal(18, 2)
  buyoutAgentSharePercent    Decimal?                @map("buyout_agent_share_percent") @db.Decimal(5, 2)
  buyoutProfitAmount         Decimal?                @map("buyout_profit_amount") @db.Decimal(18, 2)
  buyoutAgentCommission      Decimal?                @map("buyout_agent_commission") @db.Decimal(18, 2)
  marketReferencePrice       Decimal?                @map("market_reference_price") @db.Decimal(18, 2)
  unitCost                   Decimal                 @default(0) @map("unit_cost") @db.Decimal(18, 2)
  malUnitPrice               Decimal?                @map("mal_unit_price") @db.Decimal(18, 2)
  subtotal                   Decimal                 @db.Decimal(18, 2)
  classificationStatus       String                  @default("FINAL") @map("classification_status") @db.VarChar(20)
  warehouseId                BigInt?                 @map("warehouse_id")
  warehouse                  Warehouse?              @relation(fields: [warehouseId], references: [id], onDelete: Restrict)
  warehouseLocationId        BigInt?                 @map("warehouse_location_id")
  warehouseLocation          WarehouseLocation?      @relation(fields: [warehouseLocationId], references: [id], onDelete: Restrict)
  notes                      String?
  createdAt                  DateTime                @default(now()) @map("created_at")
  updatedAt                  DateTime                @updatedAt @map("updated_at")
  receiptLines               ReceiptLine[]
  lots                       InventoryLot[]
  lotAllocations             LotPurchaseAllocation[]

  @@map("purchase_lines")
}

model Receipt {
  id           BigInt         @id @default(autoincrement())
  receiptNo    String         @unique @map("receipt_no") @db.VarChar(50)
  purchaseId   BigInt         @map("purchase_id")
  purchase     Purchase       @relation(fields: [purchaseId], references: [id], onDelete: Restrict)
  receiptDate  DateTime       @map("receipt_date") @db.Date
  status       String         @default("DRAFT") @db.VarChar(20)
  notes        String?
  receivedById BigInt         @map("received_by")
  receivedBy   User           @relation(fields: [receivedById], references: [id], onDelete: Restrict)
  createdAt    DateTime       @default(now()) @map("created_at")
  updatedAt    DateTime       @updatedAt @map("updated_at")
  lines        ReceiptLine[]
  lots         InventoryLot[]

  @@map("receipts")
}

model ReceiptLine {
  id                  BigInt             @id @default(autoincrement())
  receiptId           BigInt             @map("receipt_id")
  receipt             Receipt            @relation(fields: [receiptId], references: [id], onDelete: Cascade)
  purchaseLineId      BigInt             @map("purchase_line_id")
  purchaseLine        PurchaseLine       @relation(fields: [purchaseLineId], references: [id], onDelete: Restrict)
  gradeId             BigInt?            @map("grade_id")
  grade               Grade?             @relation(fields: [gradeId], references: [id], onDelete: Restrict)
  qtyReceived         Decimal            @map("qty_received") @db.Decimal(18, 3)
  qtyAccepted         Decimal            @map("qty_accepted") @db.Decimal(18, 3)
  qtyRejected         Decimal            @default(0) @map("qty_rejected") @db.Decimal(18, 3)
  moisturePercent     Decimal?           @map("moisture_percent") @db.Decimal(7, 2)
  unitId              BigInt             @map("unit_id")
  unit                Unit               @relation(fields: [unitId], references: [id], onDelete: Restrict)
  unitCost            Decimal            @map("unit_cost") @db.Decimal(18, 2)
  warehouseId         BigInt             @map("warehouse_id")
  warehouse           Warehouse          @relation(fields: [warehouseId], references: [id], onDelete: Restrict)
  warehouseLocationId BigInt?            @map("warehouse_location_id")
  warehouseLocation   WarehouseLocation? @relation(fields: [warehouseLocationId], references: [id], onDelete: Restrict)
  notes               String?
  createdAt           DateTime           @default(now()) @map("created_at")
  updatedAt           DateTime           @updatedAt @map("updated_at")
  lots                InventoryLot[]

  @@map("receipt_lines")
}

model InventoryLot {
  id                       BigInt                     @id @default(autoincrement())
  lotCode                  String                     @unique @map("lot_code") @db.VarChar(100)
  parentLotId              BigInt?                    @map("parent_lot_id")
  parentLot                InventoryLot?              @relation("LotHierarchy", fields: [parentLotId], references: [id], onDelete: Restrict)
  childLots                InventoryLot[]             @relation("LotHierarchy")
  sourceType               String                     @map("source_type") @db.VarChar(30)
  sourceRefId              BigInt?                    @map("source_ref_id")
  purchaseId               BigInt?                    @map("purchase_id")
  purchase                 Purchase?                  @relation(fields: [purchaseId], references: [id], onDelete: Restrict)
  purchaseLineId           BigInt?                    @map("purchase_line_id")
  purchaseLine             PurchaseLine?              @relation(fields: [purchaseLineId], references: [id], onDelete: Restrict)
  receiptId                BigInt?                    @map("receipt_id")
  receipt                  Receipt?                   @relation(fields: [receiptId], references: [id], onDelete: Restrict)
  receiptLineId            BigInt?                    @map("receipt_line_id")
  receiptLine              ReceiptLine?               @relation(fields: [receiptLineId], references: [id], onDelete: Restrict)
  gradeId                  BigInt?                    @map("grade_id")
  grade                    Grade?                     @relation(fields: [gradeId], references: [id], onDelete: Restrict)
  warehouseId              BigInt                     @map("warehouse_id")
  warehouse                Warehouse                  @relation(fields: [warehouseId], references: [id], onDelete: Restrict)
  warehouseLocationId      BigInt?                    @map("warehouse_location_id")
  warehouseLocation        WarehouseLocation?         @relation(fields: [warehouseLocationId], references: [id], onDelete: Restrict)
  originalQty              Decimal                    @map("original_qty") @db.Decimal(18, 3)
  availableQty             Decimal                    @map("available_qty") @db.Decimal(18, 3)
  reservedQty              Decimal                    @default(0) @map("reserved_qty") @db.Decimal(18, 3)
  damagedQty               Decimal                    @default(0) @map("damaged_qty") @db.Decimal(18, 3)
  shrinkageQty             Decimal                    @default(0) @map("shrinkage_qty") @db.Decimal(18, 3)
  finalMoisturePercent     Decimal?                   @map("final_moisture_percent") @db.Decimal(7, 2)
  aboveAverageRatioPercent Decimal?                   @map("above_average_ratio_percent") @db.Decimal(7, 2)
  unitId                   BigInt                     @map("unit_id")
  unit                     Unit                       @relation(fields: [unitId], references: [id], onDelete: Restrict)
  unitCost                 Decimal                    @map("unit_cost") @db.Decimal(18, 2)
  receivedAt               DateTime                   @map("received_at")
  status                   String                     @default("ACTIVE") @db.VarChar(20)
  qrCodeValue              String?                    @map("qr_code_value") @db.VarChar(255)
  barcodeValue             String?                    @map("barcode_value") @db.VarChar(255)
  notes                    String?
  createdAt                DateTime                   @default(now()) @map("created_at")
  updatedAt                DateTime                   @updatedAt @map("updated_at")
  sourcedBuyoutLines       PurchaseLine[]             @relation("OfficeBuyoutSourceLot")
  transformationInputs     LotTransformationInput[]   @relation("TransformationInputLot")
  transformationOutputs    LotTransformationOutput[]  @relation("TransformationOutputLot")
  stockAdjustments         StockAdjustment[]
  washings                 LotWashing[]
  consignmentLines         ConsignmentLine[]
  regularSaleLines         RegularSaleLine[]
  purchaseAllocations      LotPurchaseAllocation[]
  realizationEntries       PurchaseRealizationEntry[]

  @@map("inventory_lots")
}

model Consignment {
  id              BigInt            @id @default(autoincrement())
  consignmentNo   String            @unique @map("consignment_no") @db.VarChar(50)
  consignmentDate DateTime          @map("consignment_date") @db.Date
  salesId         BigInt            @map("sales_id")
  sales           Sales             @relation("ConsignmentSales", fields: [salesId], references: [id], onDelete: Restrict)
  buyerId         BigInt            @map("buyer_id")
  buyer           Buyer             @relation("ConsignmentBuyer", fields: [buyerId], references: [id], onDelete: Restrict)
  status          String            @default("OPEN") @db.VarChar(20)
  notes           String?
  createdById     BigInt            @map("created_by")
  createdBy       User              @relation("ConsignmentCreatedBy", fields: [createdById], references: [id], onDelete: Restrict)
  createdAt       DateTime          @default(now()) @map("created_at")
  updatedAt       DateTime          @updatedAt @map("updated_at")
  lines           ConsignmentLine[]

  @@map("consignments")
}

model ConsignmentLine {
  id                   BigInt       @id @default(autoincrement())
  consignmentId        BigInt       @map("consignment_id")
  consignment          Consignment  @relation(fields: [consignmentId], references: [id], onDelete: Cascade)
  lotId                BigInt       @map("lot_id")
  lot                  InventoryLot @relation(fields: [lotId], references: [id], onDelete: Restrict)
  qtyConsigned         Decimal      @map("qty_consigned") @db.Decimal(18, 3)
  availableQtySnapshot Decimal      @map("available_qty_snapshot") @db.Decimal(18, 3)
  malUnitPriceSnapshot Decimal?     @map("mal_unit_price_snapshot") @db.Decimal(18, 2)
  agentNameSnapshot    String?      @map("agent_name_snapshot") @db.VarChar(150)
  agentSharePercent    Decimal?     @map("agent_share_percent") @db.Decimal(5, 2)
  status               String       @default("OPEN") @db.VarChar(20)
  notes                String?
  closeDate            DateTime?    @map("close_date") @db.Date
  sellingPrice         Decimal?     @map("selling_price") @db.Decimal(18, 2)
  qtySold              Decimal      @default(0) @map("qty_sold") @db.Decimal(18, 3)
  qtyReturned          Decimal      @default(0) @map("qty_returned") @db.Decimal(18, 3)
  qtyShrinkage         Decimal      @default(0) @map("qty_shrinkage") @db.Decimal(18, 3)
  salesCommission      Decimal      @default(0) @map("sales_commission") @db.Decimal(18, 2)
  agentCommission      Decimal      @default(0) @map("agent_commission") @db.Decimal(18, 2)
  createdAt            DateTime     @default(now()) @map("created_at")
  updatedAt            DateTime     @updatedAt @map("updated_at")

  @@map("consignment_lines")
}

model RegularSale {
  id                     BigInt            @id @default(autoincrement())
  saleNo                 String            @unique @map("sale_no") @db.VarChar(50)
  saleDate               DateTime          @map("sale_date") @db.Date
  buyerId                BigInt            @map("buyer_id")
  buyer                  Buyer             @relation("RegularSaleBuyer", fields: [buyerId], references: [id], onDelete: Restrict)
  buyerCurrencyCode      String            @map("buyer_currency_code") @db.VarChar(10)
  companyCurrencyCode    String            @map("company_currency_code") @db.VarChar(10)
  exchangeRate           Decimal?          @map("exchange_rate") @db.Decimal(18, 6)
  courierId              BigInt?           @map("courier_id")
  courier                Courier?          @relation(fields: [courierId], references: [id], onDelete: Restrict)
  shippingCostBuyer      Decimal           @default(0) @map("shipping_cost_buyer") @db.Decimal(18, 2)
  shippingCostCompany    Decimal           @default(0) @map("shipping_cost_company") @db.Decimal(18, 2)
  shippingReceiptFileUrl String?           @map("shipping_receipt_file_url") @db.VarChar(255)
  closeDate              DateTime?         @map("close_date") @db.Date
  totalNominalBuyer      Decimal           @default(0) @map("total_nominal_buyer") @db.Decimal(18, 2)
  totalNominalCompany    Decimal           @default(0) @map("total_nominal_company") @db.Decimal(18, 2)
  totalAgentCommission   Decimal           @default(0) @map("total_agent_commission") @db.Decimal(18, 2)
  status                 String            @default("IN_PROGRESS") @db.VarChar(20)
  notes                  String?
  createdById            BigInt            @map("created_by")
  createdBy              User              @relation("RegularSaleCreatedBy", fields: [createdById], references: [id], onDelete: Restrict)
  createdAt              DateTime          @default(now()) @map("created_at")
  updatedAt              DateTime          @updatedAt @map("updated_at")
  lines                  RegularSaleLine[]

  @@map("regular_sales")
}

model RegularSaleLine {
  id                   BigInt       @id @default(autoincrement())
  regularSaleId        BigInt       @map("regular_sale_id")
  regularSale          RegularSale  @relation(fields: [regularSaleId], references: [id], onDelete: Cascade)
  lotId                BigInt       @map("lot_id")
  lot                  InventoryLot @relation(fields: [lotId], references: [id], onDelete: Restrict)
  availableQtySnapshot Decimal      @map("available_qty_snapshot") @db.Decimal(18, 3)
  malUnitPriceSnapshot Decimal?     @map("mal_unit_price_snapshot") @db.Decimal(18, 2)
  agentId              BigInt?      @map("agent_id")
  agentNameSnapshot    String?      @map("agent_name_snapshot") @db.VarChar(150)
  agentSharePercent    Decimal?     @map("agent_share_percent") @db.Decimal(5, 2)
  qtyPlanned           Decimal      @map("qty_planned") @db.Decimal(18, 3)
  sellingPricePlanned  Decimal      @map("selling_price_planned") @db.Decimal(18, 2)
  qtyActualSold        Decimal?     @map("qty_actual_sold") @db.Decimal(18, 3)
  qtyReturned          Decimal?     @map("qty_returned") @db.Decimal(18, 3)
  qtyShrinkage         Decimal?     @map("qty_shrinkage") @db.Decimal(18, 3)
  sellingPriceActual   Decimal?     @map("selling_price_actual") @db.Decimal(18, 2)
  notes                String?
  createdAt            DateTime     @default(now()) @map("created_at")
  updatedAt            DateTime     @updatedAt @map("updated_at")

  @@unique([regularSaleId, lotId])
  @@map("regular_sale_lines")
}

model JitSale {
  id                     BigInt        @id @default(autoincrement())
  saleNo                 String        @unique @map("sale_no") @db.VarChar(50)
  saleDate               DateTime      @map("sale_date") @db.Date
  buyerId                BigInt        @map("buyer_id")
  buyer                  Buyer         @relation("JitSaleBuyer", fields: [buyerId], references: [id], onDelete: Restrict)
  buyerCurrencyCode      String        @map("buyer_currency_code") @db.VarChar(10)
  companyCurrencyCode    String        @map("company_currency_code") @db.VarChar(10)
  exchangeRate           Decimal?      @map("exchange_rate") @db.Decimal(18, 6)
  courierId              BigInt?       @map("courier_id")
  courier                Courier?      @relation(fields: [courierId], references: [id], onDelete: Restrict)
  shippingCostBuyer      Decimal       @default(0) @map("shipping_cost_buyer") @db.Decimal(18, 2)
  shippingCostCompany    Decimal       @default(0) @map("shipping_cost_company") @db.Decimal(18, 2)
  shippingReceiptFileUrl String?       @map("shipping_receipt_file_url") @db.VarChar(255)
  closeDate              DateTime?     @map("close_date") @db.Date
  totalNominalBuyer      Decimal       @default(0) @map("total_nominal_buyer") @db.Decimal(18, 2)
  totalNominalCompany    Decimal       @default(0) @map("total_nominal_company") @db.Decimal(18, 2)
  totalAgentCommission   Decimal       @default(0) @map("total_agent_commission") @db.Decimal(18, 2)
  status                 String        @default("OPEN") @db.VarChar(20)
  notes                  String?
  createdById            BigInt        @map("created_by")
  createdBy              User          @relation("JitSaleCreatedBy", fields: [createdById], references: [id], onDelete: Restrict)
  createdAt              DateTime      @default(now()) @map("created_at")
  updatedAt              DateTime      @updatedAt @map("updated_at")
  lines                  JitSaleLine[]

  @@map("jit_sales")
}

model JitSaleLine {
  id                    BigInt             @id @default(autoincrement())
  jitSaleId             BigInt             @map("jit_sale_id")
  jitSale               JitSale            @relation(fields: [jitSaleId], references: [id], onDelete: Cascade)
  gradeId               BigInt             @map("grade_id")
  grade                 Grade              @relation(fields: [gradeId], references: [id], onDelete: Restrict)
  qtyPlanned            Decimal            @map("qty_planned") @db.Decimal(18, 3)
  qtyActualSold         Decimal?           @map("qty_actual_sold") @db.Decimal(18, 3)
  malUnitPrice          Decimal            @map("mal_unit_price") @db.Decimal(18, 2)
  sellingPricePlanned   Decimal            @map("selling_price_planned") @db.Decimal(18, 2)
  sellingPriceActual    Decimal?           @map("selling_price_actual") @db.Decimal(18, 2)
  agentId               BigInt?            @map("agent_id")
  agent                 Agent?             @relation(fields: [agentId], references: [id], onDelete: Restrict)
  agentNameSnapshot     String?            @map("agent_name_snapshot") @db.VarChar(150)
  profitShareSchemeId   BigInt?            @map("profit_share_scheme_id")
  profitShareScheme     ProfitShareScheme? @relation(fields: [profitShareSchemeId], references: [id], onDelete: Restrict)
  profitShareSchemeName String?            @map("profit_share_scheme_name") @db.VarChar(150)
  agentSharePercent     Decimal?           @map("agent_share_percent") @db.Decimal(5, 2)
  notes                 String?
  createdAt             DateTime           @default(now()) @map("created_at")
  updatedAt             DateTime           @updatedAt @map("updated_at")

  @@map("jit_sale_lines")
}

model StockAdjustment {
  id                 BigInt           @id @default(autoincrement())
  adjustmentNo       String           @unique @map("adjustment_no") @db.VarChar(50)
  lotId              BigInt           @map("lot_id")
  lot                InventoryLot     @relation(fields: [lotId], references: [id], onDelete: Restrict)
  adjustmentReasonId BigInt           @map("adjustment_reason_id")
  adjustmentReason   AdjustmentReason @relation(fields: [adjustmentReasonId], references: [id], onDelete: Restrict)
  adjustmentDate     DateTime         @map("adjustment_date") @db.Date
  qtyChange          Decimal          @map("qty_change") @db.Decimal(18, 3)
  availableQtyBefore Decimal          @map("available_qty_before") @db.Decimal(18, 3)
  availableQtyAfter  Decimal          @map("available_qty_after") @db.Decimal(18, 3)
  notes              String?
  createdById        BigInt           @map("created_by")
  createdBy          User             @relation("StockAdjustmentCreatedBy", fields: [createdById], references: [id], onDelete: Restrict)
  createdAt          DateTime         @default(now()) @map("created_at")
  updatedAt          DateTime         @updatedAt @map("updated_at")

  @@map("stock_adjustments")
}

model LotTransformation {
  id                 BigInt                    @id @default(autoincrement())
  transformationNo   String                    @unique @map("transformation_no") @db.VarChar(50)
  transformationType String                    @default("MIX") @map("transformation_type") @db.VarChar(30)
  transformationDate DateTime                  @map("transformation_date") @db.Date
  status             String                    @default("FINALIZED") @db.VarChar(20)
  remainderMode      String?                   @map("remainder_mode") @db.VarChar(30)
  remainderQty       Decimal?                  @map("remainder_qty") @db.Decimal(18, 3)
  processingLossMode String?                   @map("processing_loss_mode") @db.VarChar(30)
  processingLossQty  Decimal?                  @map("processing_loss_qty") @db.Decimal(18, 3)
  notes              String?
  createdById        BigInt                    @map("created_by")
  createdBy          User                      @relation("TransformationCreatedBy", fields: [createdById], references: [id], onDelete: Restrict)
  createdAt          DateTime                  @default(now()) @map("created_at")
  updatedAt          DateTime                  @updatedAt @map("updated_at")
  inputs             LotTransformationInput[]
  outputs            LotTransformationOutput[]

  @@map("lot_transformations")
}

model LotTransformationInput {
  id               BigInt            @id @default(autoincrement())
  transformationId BigInt            @map("transformation_id")
  transformation   LotTransformation @relation(fields: [transformationId], references: [id], onDelete: Cascade)
  sourceLotId      BigInt            @map("source_lot_id")
  sourceLot        InventoryLot      @relation("TransformationInputLot", fields: [sourceLotId], references: [id], onDelete: Restrict)
  qtyUsed          Decimal           @map("qty_used") @db.Decimal(18, 3)
  unitCostSnapshot Decimal           @map("unit_cost_snapshot") @db.Decimal(18, 2)
  notes            String?
  createdAt        DateTime          @default(now()) @map("created_at")
  updatedAt        DateTime          @updatedAt @map("updated_at")

  @@unique([transformationId, sourceLotId])
  @@map("lot_transformation_inputs")
}

model LotTransformationOutput {
  id               BigInt            @id @default(autoincrement())
  transformationId BigInt            @map("transformation_id")
  transformation   LotTransformation @relation(fields: [transformationId], references: [id], onDelete: Cascade)
  resultLotId      BigInt            @unique @map("result_lot_id")
  resultLot        InventoryLot      @relation("TransformationOutputLot", fields: [resultLotId], references: [id], onDelete: Restrict)
  qtyProduced      Decimal           @map("qty_produced") @db.Decimal(18, 3)
  notes            String?
  createdAt        DateTime          @default(now()) @map("created_at")
  updatedAt        DateTime          @updatedAt @map("updated_at")

  @@map("lot_transformation_outputs")
}

model PurchaseAnalysis {
  id                       BigInt                      @id @default(autoincrement())
  purchaseId               BigInt                      @unique @map("purchase_id")
  purchase                 Purchase                    @relation(fields: [purchaseId], references: [id], onDelete: Cascade)
  status                   String                      @default("DRAFT") @db.VarChar(20)
  weightBuy                Decimal?                    @map("weight_buy") @db.Decimal(18, 3)
  weightReceived           Decimal?                    @map("weight_received") @db.Decimal(18, 3)
  weightFinal              Decimal?                    @map("weight_final") @db.Decimal(18, 3)
  moistureBuyPercent       Decimal?                    @map("moisture_buy_percent") @db.Decimal(7, 2)
  moistureReceivedPercent  Decimal?                    @map("moisture_received_percent") @db.Decimal(7, 2)
  moistureFinalPercent     Decimal?                    @map("moisture_final_percent") @db.Decimal(7, 2)
  aboveAverageRatioPercent Decimal?                    @map("above_average_ratio_percent") @db.Decimal(7, 2)
  averagePrice             Decimal?                    @map("average_price") @db.Decimal(18, 2)
  modalBeli                Decimal?                    @map("modal_beli") @db.Decimal(18, 2)
  modalMasuk               Decimal?                    @map("modal_masuk") @db.Decimal(18, 2)
  modalJual                Decimal?                    @map("modal_jual") @db.Decimal(18, 2)
  modalBarang              Decimal?                    @map("modal_barang") @db.Decimal(18, 2)
  totalModalBeli           Decimal?                    @map("total_modal_beli") @db.Decimal(18, 2)
  totalModalMal            Decimal?                    @map("total_modal_mal") @db.Decimal(18, 2)
  marketReferencePrice     Decimal?                    @map("market_reference_price") @db.Decimal(18, 2)
  marketValuationTotal     Decimal?                    @map("market_valuation_total") @db.Decimal(18, 2)
  agentProfitShareTotal    Decimal                     @default(0) @map("agent_profit_share_total") @db.Decimal(18, 2)
  notes                    String?
  createdAt                DateTime                    @default(now()) @map("created_at")
  updatedAt                DateTime                    @updatedAt @map("updated_at")
  costEntries              PurchaseAnalysisCostEntry[]

  @@map("purchase_analyses")
}

model PurchaseAnalysisCostEntry {
  id           BigInt           @id @default(autoincrement())
  analysisId   BigInt           @map("analysis_id")
  analysis     PurchaseAnalysis @relation(fields: [analysisId], references: [id], onDelete: Cascade)
  costType     String           @map("cost_type") @db.VarChar(50)
  description  String?          @db.VarChar(255)
  amount       Decimal          @db.Decimal(18, 2)
  proofFileUrl String?          @map("proof_file_url") @db.VarChar(255)
  createdAt    DateTime         @default(now()) @map("created_at")
  updatedAt    DateTime         @updatedAt @map("updated_at")

  @@map("purchase_analysis_cost_entries")
}

model LotPurchaseAllocation {
  id                          BigInt                     @id @default(autoincrement())
  lotId                       BigInt                     @map("lot_id")
  lot                         InventoryLot               @relation(fields: [lotId], references: [id], onDelete: Cascade)
  purchaseId                  BigInt                     @map("purchase_id")
  purchase                    Purchase                   @relation(fields: [purchaseId], references: [id], onDelete: Cascade)
  purchaseLineId              BigInt?                    @map("purchase_line_id")
  purchaseLine                PurchaseLine?              @relation(fields: [purchaseLineId], references: [id], onDelete: SetNull)
  sourceType                  String                     @map("source_type") @db.VarChar(30)
  sourceRefId                 BigInt?                    @map("source_ref_id")
  agentIdSnapshot             BigInt?                    @map("agent_id_snapshot")
  profitShareSchemeIdSnapshot BigInt?                    @map("profit_share_scheme_id_snapshot")
  qtyAllocated                Decimal                    @map("qty_allocated") @db.Decimal(18, 3)
  costTotalAllocated          Decimal                    @map("cost_total_allocated") @db.Decimal(18, 2)
  unitCostSnapshot            Decimal                    @map("unit_cost_snapshot") @db.Decimal(18, 2)
  notes                       String?
  createdAt                   DateTime                   @default(now()) @map("created_at")
  updatedAt                   DateTime                   @updatedAt @map("updated_at")
  realizationEntries          PurchaseRealizationEntry[]

  @@index([lotId])
  @@index([purchaseId])
  @@index([purchaseLineId])
  @@index([sourceType, sourceRefId])
  @@map("lot_purchase_allocations")
}

model PurchaseRealizationEntry {
  id                        BigInt                 @id @default(autoincrement())
  purchaseId                BigInt                 @map("purchase_id")
  purchase                  Purchase               @relation(fields: [purchaseId], references: [id], onDelete: Cascade)
  lotId                     BigInt?                @map("lot_id")
  lot                       InventoryLot?          @relation(fields: [lotId], references: [id], onDelete: SetNull)
  allocationId              BigInt?                @map("allocation_id")
  allocation                LotPurchaseAllocation? @relation(fields: [allocationId], references: [id], onDelete: SetNull)
  eventType                 String                 @map("event_type") @db.VarChar(40)
  referenceType             String                 @map("reference_type") @db.VarChar(40)
  referenceId               BigInt?                @map("reference_id")
  occurredAt                DateTime               @map("occurred_at")
  qtyIn                     Decimal                @default(0) @map("qty_in") @db.Decimal(18, 3)
  qtyOut                    Decimal                @default(0) @map("qty_out") @db.Decimal(18, 3)
  qtyShrinkage              Decimal                @default(0) @map("qty_shrinkage") @db.Decimal(18, 3)
  amountCost                Decimal                @default(0) @map("amount_cost") @db.Decimal(18, 2)
  amountRevenue             Decimal                @default(0) @map("amount_revenue") @db.Decimal(18, 2)
  amountExpense             Decimal                @default(0) @map("amount_expense") @db.Decimal(18, 2)
  amountProfit              Decimal                @default(0) @map("amount_profit") @db.Decimal(18, 2)
  agentSharePercentSnapshot Decimal?               @map("agent_share_percent_snapshot") @db.Decimal(7, 2)
  agentAmount               Decimal                @default(0) @map("agent_amount") @db.Decimal(18, 2)
  notes                     String?
  createdAt                 DateTime               @default(now()) @map("created_at")
  updatedAt                 DateTime               @updatedAt @map("updated_at")

  @@index([purchaseId, occurredAt])
  @@index([lotId])
  @@index([allocationId])
  @@index([referenceType, referenceId])
  @@index([eventType, occurredAt])
  @@map("purchase_realization_entries")
}

model PurchaseRealizationSummary {
  id                  BigInt    @id @default(autoincrement())
  purchaseId          BigInt    @unique @map("purchase_id")
  purchase            Purchase  @relation(fields: [purchaseId], references: [id], onDelete: Cascade)
  status              String    @default("OPEN") @db.VarChar(20)
  qtyOpening          Decimal   @default(0) @map("qty_opening") @db.Decimal(18, 3)
  qtyRemaining        Decimal   @default(0) @map("qty_remaining") @db.Decimal(18, 3)
  qtySold             Decimal   @default(0) @map("qty_sold") @db.Decimal(18, 3)
  qtyReturned         Decimal   @default(0) @map("qty_returned") @db.Decimal(18, 3)
  qtyShrinkage        Decimal   @default(0) @map("qty_shrinkage") @db.Decimal(18, 3)
  costOpeningTotal    Decimal   @default(0) @map("cost_opening_total") @db.Decimal(18, 2)
  costAdditionalTotal Decimal   @default(0) @map("cost_additional_total") @db.Decimal(18, 2)
  revenueTotal        Decimal   @default(0) @map("revenue_total") @db.Decimal(18, 2)
  profitLossTotal     Decimal   @default(0) @map("profit_loss_total") @db.Decimal(18, 2)
  agentSharePercent   Decimal?  @map("agent_share_percent") @db.Decimal(7, 2)
  agentProfitTotal    Decimal   @default(0) @map("agent_profit_total") @db.Decimal(18, 2)
  closedAt            DateTime? @map("closed_at")
  createdAt           DateTime  @default(now()) @map("created_at")
  updatedAt           DateTime  @updatedAt @map("updated_at")

  @@index([status])
  @@index([closedAt])
  @@map("purchase_realization_summaries")
}

model LotWashing {
  id                  BigInt       @id @default(autoincrement())
  washingNo           String       @unique @map("washing_no") @db.VarChar(50)
  lotId               BigInt       @map("lot_id")
  lot                 InventoryLot @relation(fields: [lotId], references: [id], onDelete: Restrict)
  washingPlaceId      BigInt       @map("washing_place_id")
  washingPlace        WashingPlace @relation(fields: [washingPlaceId], references: [id], onDelete: Restrict)
  washingCost         Decimal      @map("washing_cost") @db.Decimal(18, 2)
  durationHours       Int          @map("duration_hours")
  receiptFileUrl      String?      @map("receipt_file_url") @db.VarChar(255)
  status              String       @default("IN_PROGRESS") @db.VarChar(20)
  startedAt           DateTime     @default(now()) @map("started_at")
  expectedDoneAt      DateTime     @map("expected_done_at")
  completedAt         DateTime?    @map("completed_at")
  beforeQty           Decimal      @map("before_qty") @db.Decimal(18, 3)
  afterQty            Decimal?     @map("after_qty") @db.Decimal(18, 3)
  shrinkageQty        Decimal?     @map("shrinkage_qty") @db.Decimal(18, 3)
  beforeGradeName     String?      @map("before_grade_name") @db.VarChar(100)
  afterGradeName      String?      @map("after_grade_name") @db.VarChar(100)
  beforeWarehouseName String       @map("before_warehouse_name") @db.VarChar(150)
  beforeLocationName  String?      @map("before_location_name") @db.VarChar(150)
  afterWarehouseName  String?      @map("after_warehouse_name") @db.VarChar(150)
  afterLocationName   String?      @map("after_location_name") @db.VarChar(150)
  createdById         BigInt       @map("created_by")
  createdBy           User         @relation("WashingCreatedBy", fields: [createdById], references: [id], onDelete: Restrict)
  completedById       BigInt?      @map("completed_by")
  completedBy         User?        @relation("WashingCompletedBy", fields: [completedById], references: [id], onDelete: Restrict)
  createdAt           DateTime     @default(now()) @map("created_at")
  updatedAt           DateTime     @updatedAt @map("updated_at")

  @@index([lotId, status])
  @@map("lot_washings")
}

model AppSetting {
  id                       BigInt               @id @default(autoincrement())
  singletonKey             String               @unique @default("SYSTEM") @map("singleton_key") @db.VarChar(30)
  companyName              String?              @map("company_name") @db.VarChar(150)
  companyEmail             String?              @map("company_email") @db.VarChar(150)
  companyPhone             String?              @map("company_phone") @db.VarChar(50)
  companyBankName          String?              @map("company_bank_name") @db.VarChar(150)
  companyBankAccountNumber String?              @map("company_bank_account_number") @db.VarChar(80)
  companyAddress           String?              @map("company_address")
  companyTimezone          String               @default("Asia/Jakarta") @map("company_timezone") @db.VarChar(80)
  smtpHost                 String?              @map("smtp_host") @db.VarChar(150)
  smtpPort                 Int?                 @map("smtp_port")
  smtpSecure               Boolean              @default(true) @map("smtp_secure")
  smtpUser                 String?              @map("smtp_user") @db.VarChar(150)
  smtpPassword             String?              @map("smtp_password") @db.VarChar(255)
  smtpFromName             String?              @map("smtp_from_name") @db.VarChar(150)
  smtpFromEmail            String?              @map("smtp_from_email") @db.VarChar(150)
  purchasePrefix           String               @default("PO") @map("purchase_prefix") @db.VarChar(20)
  receiptPrefix            String               @default("RCV") @map("receipt_prefix") @db.VarChar(20)
  lotPrefix                String               @default("LOT") @map("lot_prefix") @db.VarChar(20)
  adjustmentPrefix         String               @default("STA") @map("adjustment_prefix") @db.VarChar(20)
  transformationPrefix     String               @default("MIX") @map("transformation_prefix") @db.VarChar(20)
  fundRequestPrefix        String               @default("FR") @map("fund_request_prefix") @db.VarChar(20)
  washingPrefix            String               @default("WSH") @map("washing_prefix") @db.VarChar(20)
  regularSalePrefix        String               @default("SRG") @map("regular_sale_prefix") @db.VarChar(20)
  jitSalePrefix            String               @default("SJT") @map("jit_sale_prefix") @db.VarChar(20)
  consignmentPrefix        String               @default("TJT") @map("consignment_prefix") @db.VarChar(20)
  defaultLocale            String               @default("id") @map("default_locale") @db.VarChar(10)
  currencyCode             String               @default("IDR") @map("currency_code") @db.VarChar(10)
  dateFormat               String               @default("DD/MM/YYYY") @map("date_format") @db.VarChar(30)
  passwordMinLength        Int                  @default(8) @map("password_min_length")
  sessionTimeoutMinutes    Int                  @default(720) @map("session_timeout_minutes")
  requireEmailVerification Boolean              @default(true) @map("require_email_verification")
  auditRetentionDays       Int                  @default(365) @map("audit_retention_days")
  createdAt                DateTime             @default(now()) @map("created_at")
  updatedAt                DateTime             @updatedAt @map("updated_at")
  companyBankAccounts      CompanyBankAccount[]

  @@map("app_settings")
}

model CompanyBankAccount {
  id            BigInt        @id @default(autoincrement())
  appSettingId  BigInt        @map("app_setting_id")
  appSetting    AppSetting    @relation(fields: [appSettingId], references: [id], onDelete: Cascade)
  bankId        BigInt        @map("bank_id")
  bank          Bank          @relation(fields: [bankId], references: [id], onDelete: Restrict)
  accountNumber String        @map("account_number") @db.VarChar(100)
  createdAt     DateTime      @default(now()) @map("created_at")
  updatedAt     DateTime      @updatedAt @map("updated_at")
  fundRequests  FundRequest[]

  @@unique([appSettingId, bankId, accountNumber])
  @@map("company_bank_accounts")
}
