generator client { provider = "prisma-client-js" } datasource db { provider = "postgresql" url = env("DATABASE_URL") } enum SettlementType { cash check } enum CheckRegistrationMode { full brief } enum OrderStatus { cart awaiting_settlement cash_in_progress check_in_progress submitted awaiting_review pricing needs_correction awaiting_settlement_fix cash_invoice_issued awaiting_cash_payment cash_payment_submitted awaiting_cash_confirmation cash_confirmed awaiting_check_review check_needs_fix check_rejected checks_approved final_approved preparing ready_to_ship shipped delivered cancelled rejected expired } enum CheckStatus { pending_review approved rejected } enum CashPaymentStatus { pending_review approved rejected expired } enum ShipmentStatus { preparing ready shipped delivered } enum CustomerType { wholesale retail } enum AdminRole { admin sales finance warehouse } enum NotificationTone { info warning success danger } model Company { id String @id @default(cuid()) name String slug String @unique description String? logoUrl String? isActive Boolean @default(true) displayOrder Int @default(0) maxMeteragePerInvoice Int @default(5000) cashInvoiceValidityHours Int @default(8) cashInvoiceValidUntilHour Int? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt bankAccounts BankAccount[] catalogs Catalog[] products Product[] orders Order[] customers Customer[] } model BankAccount { id String @id @default(cuid()) companyId String bankName String accountHolder String accountNumber String cardNumber String iban String notes String? isActive Boolean @default(true) displayOrder Int @default(0) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt company Company @relation(fields: [companyId], references: [id], onDelete: Cascade) cashReceipts CashPaymentReceipt[] @@index([companyId]) } model Catalog { id String @id @default(cuid()) companyId String name String code String description String? displayOrder Int @default(0) isActive Boolean @default(true) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt company Company @relation(fields: [companyId], references: [id], onDelete: Cascade) products Product[] @@unique([companyId, code]) @@index([companyId]) } model Product { id String @id @default(cuid()) companyId String catalogId String name String code String color String description String? minMeterage Float @default(30) orderMultiplier Float @default(10) basePrice Float? stock Float? isActive Boolean @default(true) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt company Company @relation(fields: [companyId], references: [id], onDelete: Cascade) catalog Catalog @relation(fields: [catalogId], references: [id], onDelete: Cascade) cartItems CartItem[] orderItems OrderItem[] @@unique([companyId, code]) @@index([catalogId]) @@index([companyId]) } model Customer { id String @id @default(cuid()) firstName String lastName String phone String @unique nationalId String? customerType CustomerType @default(wholesale) companyId String? isActive Boolean @default(true) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt company Company? @relation(fields: [companyId], references: [id], onDelete: SetNull) carts Cart[] orders Order[] @@index([companyId]) } model AdminUser { id String @id @default(cuid()) fullName String phone String @unique email String @unique passwordHash String role AdminRole @default(admin) isActive Boolean @default(true) lastLoginAt DateTime? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt } model OtpChallenge { id String @id @default(cuid()) phone String code String firstName String? lastName String? isRegister Boolean @default(false) expiresAt DateTime createdAt DateTime @default(now()) @@index([phone]) } model Cart { id String @id @default(cuid()) userId String companyId String? notes String? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt user Customer @relation(fields: [userId], references: [id], onDelete: Cascade) items CartItem[] @@index([userId]) } model CartItem { id String @id @default(cuid()) cartId String productId String catalogCode String productName String productCode String color String meterage Float unitPrice Float? notes String? companyId String companyName String cart Cart @relation(fields: [cartId], references: [id], onDelete: Cascade) product Product @relation(fields: [productId], references: [id], onDelete: Restrict) @@unique([cartId, productId]) @@index([cartId]) } model Order { id String @id @default(cuid()) orderNumber String @unique userId String companyId String companyName String settlementType SettlementType checkMode CheckRegistrationMode? status OrderStatus @default(awaiting_review) totalMeterage Float @default(0) totalAmount Float? shippingCost Float? totalDiscount Float? finalAmount Float? notes String? checkRassDays Int? checkRassDate DateTime? cashInvoiceExpiresAt DateTime? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt user Customer @relation(fields: [userId], references: [id], onDelete: Restrict) company Company @relation(fields: [companyId], references: [id], onDelete: Restrict) items OrderItem[] checks Check[] cashReceipt CashPaymentReceipt? shipment Shipment? statusHistory OrderStatusHistory[] @@index([userId]) @@index([companyId]) @@index([status]) @@index([createdAt]) } model OrderItem { id String @id @default(cuid()) orderId String productId String? catalogCode String productName String productCode String? color String requestedMeterage Float confirmedMeterage Float? unitPrice Float? unitDiscount Float? @default(0) lineTotal Float? notes String? order Order @relation(fields: [orderId], references: [id], onDelete: Cascade) product Product? @relation(fields: [productId], references: [id], onDelete: SetNull) @@index([orderId]) } model OrderStatusHistory { id String @id @default(cuid()) orderId String fromStatus OrderStatus? toStatus OrderStatus changedBy String note String? reason String? changedAt DateTime @default(now()) order Order @relation(fields: [orderId], references: [id], onDelete: Cascade) @@index([orderId]) } model Check { id String @id @default(cuid()) orderId String row Int amount Float dueDate DateTime sayadId String? checkNumber String? ownerNationalId String? ownerFirstName String? ownerLastName String? bankName String? branchName String? frontImage String? backImage String? notes String? mode CheckRegistrationMode @default(full) status CheckStatus @default(pending_review) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt order Order @relation(fields: [orderId], references: [id], onDelete: Cascade) @@index([orderId]) @@index([dueDate]) } model CashPaymentReceipt { id String @id @default(cuid()) orderId String @unique amount Float paidAmount Float? transferDate DateTime? transferTime String? trackingNumber String? destinationAccountId String? receiptImage String? notes String? expiresAt DateTime? status CashPaymentStatus @default(pending_review) submittedAt DateTime? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt order Order @relation(fields: [orderId], references: [id], onDelete: Cascade) destinationAccount BankAccount? @relation(fields: [destinationAccountId], references: [id], onDelete: SetNull) } model Shipment { id String @id @default(cuid()) orderId String @unique carrier String trackingNumber String? meterage Float status ShipmentStatus @default(preparing) shippedAt DateTime? deliveredAt DateTime? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt order Order @relation(fields: [orderId], references: [id], onDelete: Cascade) } model SystemSettings { id String @id @default("default") maxMeteragePerInvoice Int @default(5000) cashInvoiceValidityHours Int @default(8) defaultSettlementCheck Boolean @default(true) defaultSettlementCash Boolean @default(true) smsOrderRegistered Boolean @default(true) smsPaymentReminder Boolean @default(true) smsCheckReview Boolean @default(true) smsShippingUpdate Boolean @default(true) supportPhone String? supportEmail String? updatedAt DateTime @updatedAt } model AdminNotification { id String @id @default(cuid()) title String body String tone NotificationTone? @default(info) link String? isRead Boolean @default(false) sentAt DateTime @default(now()) } model InternalMessage { id String @id @default(cuid()) senderName String subject String preview String isRead Boolean @default(false) sentAt DateTime @default(now()) }