generator client {
  provider = "prisma-client-js"
}

generator seed {
  provider = "prisma-client-js"
  output   = "./generated/client"
}

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

model User {
  id             String        @id @default(cuid())
  phone          String        @unique
  avatar         String?
  managerName    String?
  createdAt      DateTime      @default(now())
  updatedAt      DateTime      @updatedAt
  organizationId String?
  sentMessages   Message[]     @relation("SentMessages")
  smsCodes       SmsCode[]
  organization   Organization? @relation(fields: [organizationId], references: [id])

  @@map("users")
}

model Admin {
  id        String    @id @default(cuid())
  username  String    @unique
  password  String
  email     String?   @unique
  isActive  Boolean   @default(true)
  lastLogin DateTime?
  createdAt DateTime  @default(now())
  updatedAt DateTime  @updatedAt

  @@map("admins")
}

model SmsCode {
  id          String   @id @default(cuid())
  code        String
  phone       String
  expiresAt   DateTime
  isUsed      Boolean  @default(false)
  attempts    Int      @default(0)
  maxAttempts Int      @default(3)
  createdAt   DateTime @default(now())
  userId      String?
  user        User?    @relation(fields: [userId], references: [id])

  @@map("sms_codes")
}

model Organization {
  id                         String                @id @default(cuid())
  inn                        String                @unique
  kpp                        String?
  name                       String?
  fullName                   String?
  ogrn                       String?
  ogrnDate                   DateTime?
  type                       OrganizationType
  market                     String?
  createdAt                  DateTime              @default(now())
  updatedAt                  DateTime              @updatedAt
  address                    String?
  addressFull                String?
  status                     String?
  actualityDate              DateTime?
  registrationDate           DateTime?
  liquidationDate            DateTime?
  managementName             String?
  managementPost             String?
  opfCode                    String?
  opfFull                    String?
  opfShort                   String?
  okato                      String?
  oktmo                      String?
  okpo                       String?
  okved                      String?
  phones                     Json?
  emails                     Json?
  employeeCount              Int?
  revenue                    BigInt?
  taxSystem                  String?
  dadataData                 Json?
  referralCode               String?               @unique
  referredById               String?
  referralPoints             Int                   @default(0)
  apiKeys                    ApiKey[]
  carts                      Cart?
  counterpartyOf             Counterparty[]        @relation("CounterpartyOf")
  organizationCounterparties Counterparty[]        @relation("OrganizationCounterparties")
  receivedRequests           CounterpartyRequest[] @relation("ReceivedRequests")
  sentRequests               CounterpartyRequest[] @relation("SentRequests")
  employees                  Employee[]
  externalAds                ExternalAd[]          @relation("ExternalAds")
  favorites                  Favorites[]
  logistics                  Logistics[]
  receivedMessages           Message[]             @relation("ReceivedMessages")
  sentMessages               Message[]             @relation("SentMessages")
  referredBy                 Organization?         @relation("ReferralRelation", fields: [referredById], references: [id])
  referrals                  Organization[]        @relation("ReferralRelation")
  products                   Product[]
  referralTransactions       ReferralTransaction[] @relation("ReferralTransactions")
  referrerTransactions       ReferralTransaction[] @relation("ReferrerTransactions")
  sellerStatsCaches          SellerStatsCache[]    @relation("SellerStatsCaches")
  services                   Service[]
  supplies                   Supply[]
  sellerSupplies             Supply[]              @relation("SellerSupplies")
  fulfillmentSupplyOrders    SupplyOrder[]         @relation("SupplyOrderFulfillmentCenter")
  logisticsSupplyOrders      SupplyOrder[]         @relation("SupplyOrderLogistics")
  supplyOrders               SupplyOrder[]
  partnerSupplyOrders        SupplyOrder[]         @relation("SupplyOrderPartner")
  supplySuppliers            SupplySupplier[]      @relation("SupplySuppliers")
  users                      User[]
  wbWarehouseCaches          WBWarehouseCache[]    @relation("WBWarehouseCaches")
  wildberriesSupplies        WildberriesSupply[]

  @@index([referralCode])
  @@index([referredById])
  @@map("organizations")
}

model ApiKey {
  id             String          @id @default(cuid())
  marketplace    MarketplaceType
  apiKey         String
  isActive       Boolean         @default(true)
  createdAt      DateTime        @default(now())
  updatedAt      DateTime        @updatedAt
  validationData Json?
  organizationId String
  organization   Organization    @relation(fields: [organizationId], references: [id])

  @@unique([organizationId, marketplace])
  @@map("api_keys")
}

model CounterpartyRequest {
  id         String                    @id @default(cuid())
  status     CounterpartyRequestStatus @default(PENDING)
  createdAt  DateTime                  @default(now())
  updatedAt  DateTime                  @updatedAt
  senderId   String
  receiverId String
  message    String?
  receiver   Organization              @relation("ReceivedRequests", fields: [receiverId], references: [id])
  sender     Organization              @relation("SentRequests", fields: [senderId], references: [id])

  @@unique([senderId, receiverId])
  @@map("counterparty_requests")
}

model Counterparty {
  id              String           @id @default(cuid())
  createdAt       DateTime         @default(now())
  organizationId  String
  counterpartyId  String
  type            CounterpartyType @default(MANUAL)
  triggeredBy     String?
  triggerEntityId String?
  counterparty    Organization     @relation("CounterpartyOf", fields: [counterpartyId], references: [id])
  organization    Organization     @relation("OrganizationCounterparties", fields: [organizationId], references: [id])

  @@unique([organizationId, counterpartyId])
  @@index([type])
  @@map("counterparties")
}

model Message {
  id                     String       @id @default(cuid())
  content                String?
  type                   MessageType  @default(TEXT)
  voiceUrl               String?
  voiceDuration          Int?
  fileUrl                String?
  fileName               String?
  fileSize               Int?
  fileType               String?
  isRead                 Boolean      @default(false)
  createdAt              DateTime     @default(now())
  updatedAt              DateTime     @updatedAt
  senderId               String
  senderOrganizationId   String
  receiverOrganizationId String
  receiverOrganization   Organization @relation("ReceivedMessages", fields: [receiverOrganizationId], references: [id])
  sender                 User         @relation("SentMessages", fields: [senderId], references: [id])
  senderOrganization     Organization @relation("SentMessages", fields: [senderOrganizationId], references: [id])

  @@index([senderOrganizationId, receiverOrganizationId, createdAt])
  @@index([receiverOrganizationId, isRead])
  @@map("messages")
}

model Service {
  id             String       @id @default(cuid())
  name           String
  description    String?
  price          Decimal      @db.Decimal(10, 2)
  imageUrl       String?
  createdAt      DateTime     @default(now())
  updatedAt      DateTime     @updatedAt
  organizationId String
  organization   Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)

  @@map("services")
}

model Supply {
  id             String        @id @default(cuid())
  name           String
  description    String?
  price          Decimal       @db.Decimal(10, 2)
  pricePerUnit   Decimal?      @db.Decimal(10, 2)
  quantity       Int           @default(0)
  unit           String        @default("шт")
  category       String        @default("Расходники")
  status         String        @default("planned")
  date           DateTime      @default(now())
  supplier       String        @default("Не указан")
  minStock       Int           @default(0)
  currentStock   Int           @default(0)
  usedStock      Int           @default(0)
  imageUrl       String?
  type           SupplyType    @default(FULFILLMENT_CONSUMABLES)
  sellerOwnerId  String?
  shopLocation   String?
  createdAt      DateTime      @default(now())
  updatedAt      DateTime      @updatedAt
  organizationId String
  organization   Organization  @relation(fields: [organizationId], references: [id], onDelete: Cascade)
  sellerOwner    Organization? @relation("SellerSupplies", fields: [sellerOwnerId], references: [id])

  @@map("supplies")
}

model Category {
  id        String    @id @default(cuid())
  name      String    @unique
  createdAt DateTime  @default(now())
  updatedAt DateTime  @updatedAt
  products  Product[]

  @@map("categories")
}

model Product {
  id               String            @id @default(cuid())
  name             String
  article          String
  description      String?
  price            Decimal           @db.Decimal(12, 2)
  pricePerSet      Decimal?          @db.Decimal(12, 2)
  quantity         Int               @default(0)
  setQuantity      Int?
  ordered          Int?
  inTransit        Int?
  stock            Int?
  sold             Int?
  type             ProductType       @default(PRODUCT)
  categoryId       String?
  brand            String?
  color            String?
  size             String?
  weight           Decimal?          @db.Decimal(8, 3)
  dimensions       String?
  material         String?
  images           Json              @default("[]")
  mainImage        String?
  isActive         Boolean           @default(true)
  createdAt        DateTime          @default(now())
  updatedAt        DateTime          @updatedAt
  organizationId   String
  cartItems        CartItem[]
  favorites        Favorites[]
  category         Category?         @relation(fields: [categoryId], references: [id])
  organization     Organization      @relation(fields: [organizationId], references: [id], onDelete: Cascade)
  supplyOrderItems SupplyOrderItem[]

  @@unique([organizationId, article])
  @@map("products")
}

model Cart {
  id             String       @id @default(cuid())
  organizationId String       @unique
  createdAt      DateTime     @default(now())
  updatedAt      DateTime     @updatedAt
  items          CartItem[]
  organization   Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)

  @@map("carts")
}

model CartItem {
  id        String   @id @default(cuid())
  cartId    String
  productId String
  quantity  Int      @default(1)
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt
  cart      Cart     @relation(fields: [cartId], references: [id], onDelete: Cascade)
  product   Product  @relation(fields: [productId], references: [id], onDelete: Cascade)

  @@unique([cartId, productId])
  @@map("cart_items")
}

model Favorites {
  id             String       @id @default(cuid())
  organizationId String
  productId      String
  createdAt      DateTime     @default(now())
  updatedAt      DateTime     @updatedAt
  organization   Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
  product        Product      @relation(fields: [productId], references: [id], onDelete: Cascade)

  @@unique([organizationId, productId])
  @@map("favorites")
}

model Employee {
  id               String             @id @default(cuid())
  firstName        String
  lastName         String
  middleName       String?
  birthDate        DateTime?
  avatar           String?
  passportPhoto    String?
  passportSeries   String?
  passportNumber   String?
  passportIssued   String?
  passportDate     DateTime?
  address          String?
  position         String
  department       String?
  hireDate         DateTime
  salary           Float?
  status           EmployeeStatus     @default(ACTIVE)
  phone            String
  email            String?
  telegram         String?
  whatsapp         String?
  emergencyContact String?
  emergencyPhone   String?
  organizationId   String
  createdAt        DateTime           @default(now())
  updatedAt        DateTime           @updatedAt
  scheduleRecords  EmployeeSchedule[]
  organization     Organization       @relation(fields: [organizationId], references: [id], onDelete: Cascade)

  @@map("employees")
}

model EmployeeSchedule {
  id            String         @id @default(cuid())
  date          DateTime
  status        ScheduleStatus
  hoursWorked   Float?
  overtimeHours Float?
  notes         String?
  employeeId    String
  createdAt     DateTime       @default(now())
  updatedAt     DateTime       @updatedAt
  employee      Employee       @relation(fields: [employeeId], references: [id], onDelete: Cascade)

  @@unique([employeeId, date])
  @@map("employee_schedules")
}

model WildberriesSupply {
  id             String                  @id @default(cuid())
  organizationId String
  deliveryDate   DateTime?
  status         WildberriesSupplyStatus @default(DRAFT)
  totalAmount    Decimal                 @db.Decimal(12, 2)
  totalItems     Int
  createdAt      DateTime                @default(now())
  updatedAt      DateTime                @updatedAt
  organization   Organization            @relation(fields: [organizationId], references: [id], onDelete: Cascade)
  cards          WildberriesSupplyCard[]

  @@map("wildberries_supplies")
}

model WildberriesSupplyCard {
  id               String            @id @default(cuid())
  supplyId         String
  nmId             String
  vendorCode       String
  title            String
  brand            String?
  price            Decimal           @db.Decimal(12, 2)
  discountedPrice  Decimal?          @db.Decimal(12, 2)
  quantity         Int
  selectedQuantity Int
  selectedMarket   String?
  selectedPlace    String?
  sellerName       String?
  sellerPhone      String?
  deliveryDate     DateTime?
  mediaFiles       Json              @default("[]")
  selectedServices Json              @default("[]")
  createdAt        DateTime          @default(now())
  updatedAt        DateTime          @updatedAt
  supply           WildberriesSupply @relation(fields: [supplyId], references: [id], onDelete: Cascade)

  @@map("wildberries_supply_cards")
}

model Logistics {
  id             String       @id @default(cuid())
  fromLocation   String
  toLocation     String
  priceUnder1m3  Float
  priceOver1m3   Float
  description    String?
  createdAt      DateTime     @default(now())
  updatedAt      DateTime     @updatedAt
  organizationId String
  organization   Organization @relation(fields: [organizationId], references: [id])

  @@map("logistics")
}

model SupplyOrder {
  id                  String            @id @default(cuid())
  partnerId           String
  deliveryDate        DateTime
  status              SupplyOrderStatus @default(PENDING)
  totalAmount         Decimal           @db.Decimal(12, 2)
  totalItems          Int
  fulfillmentCenterId String?
  logisticsPartnerId  String?
  consumableType      String?
  createdAt           DateTime          @default(now())
  updatedAt           DateTime          @updatedAt
  organizationId      String
  items               SupplyOrderItem[]
  fulfillmentCenter   Organization?     @relation("SupplyOrderFulfillmentCenter", fields: [fulfillmentCenterId], references: [id])
  logisticsPartner    Organization?     @relation("SupplyOrderLogistics", fields: [logisticsPartnerId], references: [id])
  organization        Organization      @relation(fields: [organizationId], references: [id], onDelete: Cascade)
  partner             Organization      @relation("SupplyOrderPartner", fields: [partnerId], references: [id])

  @@map("supply_orders")
}

model SupplyOrderItem {
  id                     String      @id @default(cuid())
  supplyOrderId          String
  productId              String
  quantity               Int
  price                  Decimal     @db.Decimal(12, 2)
  totalPrice             Decimal     @db.Decimal(12, 2)
  services               String[]    @default([])
  fulfillmentConsumables String[]    @default([])
  sellerConsumables      String[]    @default([])
  marketplaceCardId      String?
  createdAt              DateTime    @default(now())
  updatedAt              DateTime    @updatedAt
  product                Product     @relation(fields: [productId], references: [id])
  supplyOrder            SupplyOrder @relation(fields: [supplyOrderId], references: [id], onDelete: Cascade)

  @@unique([supplyOrderId, productId])
  @@map("supply_order_items")
}

model SupplySupplier {
  id             String       @id @default(cuid())
  name           String
  contactName    String
  phone          String
  market         String?
  address        String?
  place          String?
  telegram       String?
  organizationId String
  createdAt      DateTime     @default(now())
  updatedAt      DateTime     @updatedAt
  organization   Organization @relation("SupplySuppliers", fields: [organizationId], references: [id], onDelete: Cascade)

  @@map("supply_suppliers")
}

model ExternalAd {
  id             String       @id @default(cuid())
  name           String
  url            String
  cost           Decimal      @db.Decimal(12, 2)
  date           DateTime
  nmId           String
  clicks         Int          @default(0)
  organizationId String
  createdAt      DateTime     @default(now())
  updatedAt      DateTime     @updatedAt
  organization   Organization @relation("ExternalAds", fields: [organizationId], references: [id], onDelete: Cascade)

  @@index([organizationId, date])
  @@map("external_ads")
}

model WBWarehouseCache {
  id             String       @id @default(cuid())
  organizationId String
  cacheDate      DateTime
  data           Json
  totalProducts  Int          @default(0)
  totalStocks    Int          @default(0)
  totalReserved  Int          @default(0)
  createdAt      DateTime     @default(now())
  updatedAt      DateTime     @updatedAt
  organization   Organization @relation("WBWarehouseCaches", fields: [organizationId], references: [id], onDelete: Cascade)

  @@unique([organizationId, cacheDate])
  @@index([organizationId, cacheDate])
  @@map("wb_warehouse_caches")
}

model SellerStatsCache {
  id                     String       @id @default(cuid())
  organizationId         String
  cacheDate              DateTime
  period                 String
  dateFrom               DateTime?
  dateTo                 DateTime?
  productsData           Json?
  productsTotalSales     Decimal?     @db.Decimal(15, 2)
  productsTotalOrders    Int?
  productsCount          Int?
  advertisingData        Json?
  advertisingTotalCost   Decimal?     @db.Decimal(15, 2)
  advertisingTotalViews  Int?
  advertisingTotalClicks Int?
  expiresAt              DateTime
  createdAt              DateTime     @default(now())
  updatedAt              DateTime     @updatedAt
  organization           Organization @relation("SellerStatsCaches", fields: [organizationId], references: [id], onDelete: Cascade)

  @@unique([organizationId, cacheDate, period, dateFrom, dateTo])
  @@index([organizationId, cacheDate])
  @@index([expiresAt])
  @@map("seller_stats_caches")
}

model ReferralTransaction {
  id          String                  @id @default(cuid())
  referrerId  String
  referralId  String
  points      Int
  type        ReferralTransactionType
  description String?
  createdAt   DateTime                @default(now())
  referral    Organization            @relation("ReferralTransactions", fields: [referralId], references: [id])
  referrer    Organization            @relation("ReferrerTransactions", fields: [referrerId], references: [id])

  @@index([referrerId, createdAt])
  @@index([referralId])
  @@map("referral_transactions")
}

enum OrganizationType {
  FULFILLMENT
  SELLER
  LOGIST
  WHOLESALE
}

enum MarketplaceType {
  WILDBERRIES
  OZON
}

enum CounterpartyRequestStatus {
  PENDING
  ACCEPTED
  REJECTED
  CANCELLED
}

enum MessageType {
  TEXT
  VOICE
  IMAGE
  FILE
}

enum EmployeeStatus {
  ACTIVE
  VACATION
  SICK
  FIRED
}

enum ScheduleStatus {
  WORK
  WEEKEND
  VACATION
  SICK
  ABSENT
}

enum SupplyOrderStatus {
  PENDING
  CONFIRMED
  IN_TRANSIT
  SUPPLIER_APPROVED
  LOGISTICS_CONFIRMED
  SHIPPED
  DELIVERED
  CANCELLED
}

enum WildberriesSupplyStatus {
  DRAFT
  CREATED
  IN_PROGRESS
  DELIVERED
  CANCELLED
}

enum ProductType {
  PRODUCT
  CONSUMABLE
}

enum SupplyType {
  FULFILLMENT_CONSUMABLES
  SELLER_CONSUMABLES
}

enum CounterpartyType {
  MANUAL
  REFERRAL
  AUTO_BUSINESS
  AUTO
}

enum ReferralTransactionType {
  REGISTRATION
  AUTO_PARTNERSHIP
  FIRST_ORDER
  MONTHLY_BONUS
}
