first commit
This commit is contained in:
798
prisma/schema.prisma
Normal file
798
prisma/schema.prisma
Normal file
@ -0,0 +1,798 @@
|
||||
generator client {
|
||||
provider = "prisma-client-js"
|
||||
output = "../src/generated/prisma"
|
||||
}
|
||||
|
||||
datasource db {
|
||||
provider = "postgresql"
|
||||
url = env("DATABASE_URL")
|
||||
}
|
||||
|
||||
model User {
|
||||
id String @id @default(cuid())
|
||||
firstName String
|
||||
lastName String
|
||||
email String @unique
|
||||
password String
|
||||
avatar String?
|
||||
role UserRole @default(ADMIN)
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
// Связь с логами аудита
|
||||
auditLogs AuditLog[]
|
||||
productHistory ProductHistory[]
|
||||
managedClients Client[] // Клиенты, которыми управляет менеджер
|
||||
balanceChanges ClientBalanceHistory[] // История изменений баланса
|
||||
|
||||
@@map("users")
|
||||
}
|
||||
|
||||
model AuditLog {
|
||||
id String @id @default(cuid())
|
||||
userId String
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
action AuditAction
|
||||
details String?
|
||||
ipAddress String?
|
||||
userAgent String?
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
@@map("audit_logs")
|
||||
}
|
||||
|
||||
// Модели каталога товаров
|
||||
model Category {
|
||||
id String @id @default(cuid())
|
||||
name String
|
||||
slug String @unique
|
||||
description String?
|
||||
seoTitle String?
|
||||
seoDescription String?
|
||||
image String?
|
||||
isHidden Boolean @default(false)
|
||||
includeSubcategoryProducts Boolean @default(false)
|
||||
parentId String?
|
||||
parent Category? @relation("CategoryHierarchy", fields: [parentId], references: [id], onDelete: Cascade)
|
||||
children Category[] @relation("CategoryHierarchy")
|
||||
products Product[]
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@map("categories")
|
||||
}
|
||||
|
||||
model Product {
|
||||
id String @id @default(cuid())
|
||||
name String
|
||||
slug String @unique
|
||||
article String? @unique
|
||||
description String?
|
||||
videoUrl String?
|
||||
wholesalePrice Float?
|
||||
retailPrice Float?
|
||||
weight Float?
|
||||
dimensions String? // ДхШхВ в формате "10x20x30"
|
||||
unit String @default("шт")
|
||||
isVisible Boolean @default(true)
|
||||
applyDiscounts Boolean @default(true)
|
||||
stock Int @default(0)
|
||||
|
||||
// Связи
|
||||
categories Category[]
|
||||
images ProductImage[]
|
||||
options ProductOption[]
|
||||
characteristics ProductCharacteristic[]
|
||||
relatedProducts Product[] @relation("RelatedProducts")
|
||||
relatedTo Product[] @relation("RelatedProducts")
|
||||
accessoryProducts Product[] @relation("AccessoryProducts")
|
||||
accessoryTo Product[] @relation("AccessoryProducts")
|
||||
history ProductHistory[]
|
||||
orderItems OrderItem[]
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@map("products")
|
||||
}
|
||||
|
||||
model ProductImage {
|
||||
id String @id @default(cuid())
|
||||
url String
|
||||
alt String?
|
||||
order Int @default(0)
|
||||
productId String
|
||||
product Product @relation(fields: [productId], references: [id], onDelete: Cascade)
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
@@map("product_images")
|
||||
}
|
||||
|
||||
model Option {
|
||||
id String @id @default(cuid())
|
||||
name String @unique
|
||||
type OptionType @default(SINGLE)
|
||||
values OptionValue[]
|
||||
products ProductOption[]
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@map("options")
|
||||
}
|
||||
|
||||
model OptionValue {
|
||||
id String @id @default(cuid())
|
||||
value String
|
||||
price Float @default(0)
|
||||
optionId String
|
||||
option Option @relation(fields: [optionId], references: [id], onDelete: Cascade)
|
||||
products ProductOption[]
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
@@map("option_values")
|
||||
}
|
||||
|
||||
model ProductOption {
|
||||
id String @id @default(cuid())
|
||||
productId String
|
||||
product Product @relation(fields: [productId], references: [id], onDelete: Cascade)
|
||||
optionId String
|
||||
option Option @relation(fields: [optionId], references: [id], onDelete: Cascade)
|
||||
optionValueId String
|
||||
optionValue OptionValue @relation(fields: [optionValueId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@unique([productId, optionId, optionValueId])
|
||||
@@map("product_options")
|
||||
}
|
||||
|
||||
model Characteristic {
|
||||
id String @id @default(cuid())
|
||||
name String @unique
|
||||
products ProductCharacteristic[]
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@map("characteristics")
|
||||
}
|
||||
|
||||
model ProductCharacteristic {
|
||||
id String @id @default(cuid())
|
||||
value String
|
||||
productId String
|
||||
product Product @relation(fields: [productId], references: [id], onDelete: Cascade)
|
||||
characteristicId String
|
||||
characteristic Characteristic @relation(fields: [characteristicId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@unique([productId, characteristicId])
|
||||
@@map("product_characteristics")
|
||||
}
|
||||
|
||||
model ProductHistory {
|
||||
id String @id @default(cuid())
|
||||
productId String
|
||||
product Product @relation(fields: [productId], references: [id], onDelete: Cascade)
|
||||
action String // CREATE, UPDATE, DELETE
|
||||
changes Json? // JSON с изменениями
|
||||
userId String?
|
||||
user User? @relation(fields: [userId], references: [id], onDelete: SetNull)
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
@@map("product_history")
|
||||
}
|
||||
|
||||
enum UserRole {
|
||||
ADMIN
|
||||
MODERATOR
|
||||
USER
|
||||
}
|
||||
|
||||
enum AuditAction {
|
||||
USER_LOGIN
|
||||
USER_LOGOUT
|
||||
USER_CREATE
|
||||
USER_UPDATE
|
||||
USER_DELETE
|
||||
PASSWORD_CHANGE
|
||||
AVATAR_UPLOAD
|
||||
PROFILE_UPDATE
|
||||
CATEGORY_CREATE
|
||||
CATEGORY_UPDATE
|
||||
CATEGORY_DELETE
|
||||
PRODUCT_CREATE
|
||||
PRODUCT_UPDATE
|
||||
PRODUCT_DELETE
|
||||
}
|
||||
|
||||
enum OptionType {
|
||||
SINGLE
|
||||
MULTIPLE
|
||||
}
|
||||
|
||||
// Модели для клиентов
|
||||
model Client {
|
||||
id String @id @default(cuid())
|
||||
clientNumber String @unique
|
||||
type ClientType @default(INDIVIDUAL)
|
||||
name String
|
||||
email String?
|
||||
phone String
|
||||
city String?
|
||||
markup Float? @default(0)
|
||||
isConfirmed Boolean @default(false)
|
||||
profileId String?
|
||||
profile ClientProfile? @relation(fields: [profileId], references: [id])
|
||||
managerId String? // Личный менеджер
|
||||
manager User? @relation(fields: [managerId], references: [id])
|
||||
balance Float @default(0)
|
||||
comment String?
|
||||
|
||||
// Уведомления
|
||||
emailNotifications Boolean @default(true)
|
||||
smsNotifications Boolean @default(true)
|
||||
pushNotifications Boolean @default(false)
|
||||
|
||||
// Поля для юридических лиц
|
||||
legalEntityType String? // ООО, ИП, АО и т.д.
|
||||
legalEntityName String? // Наименование юрлица
|
||||
inn String?
|
||||
kpp String?
|
||||
ogrn String?
|
||||
okpo String?
|
||||
legalAddress String?
|
||||
actualAddress String?
|
||||
bankAccount String?
|
||||
bankName String?
|
||||
bankBik String?
|
||||
correspondentAccount String?
|
||||
|
||||
// Связи
|
||||
vehicles ClientVehicle[]
|
||||
discounts ClientDiscount[]
|
||||
deliveryAddresses ClientDeliveryAddress[]
|
||||
contacts ClientContact[]
|
||||
contracts ClientContract[]
|
||||
legalEntities ClientLegalEntity[]
|
||||
bankDetails ClientBankDetails[]
|
||||
balanceHistory ClientBalanceHistory[]
|
||||
orders Order[]
|
||||
partsSearchHistory PartsSearchHistory[]
|
||||
favorites Favorite[]
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@map("clients")
|
||||
}
|
||||
|
||||
// Модель для избранных товаров
|
||||
model Favorite {
|
||||
id String @id @default(cuid())
|
||||
clientId String
|
||||
client Client @relation(fields: [clientId], references: [id], onDelete: Cascade)
|
||||
|
||||
// Данные о товаре - для внешних товаров (AutoEuro, PartsAPI)
|
||||
productId String? // ID товара во внешней системе или внутренний ID
|
||||
offerKey String? // Ключ предложения (для AutoEuro)
|
||||
name String // Название товара
|
||||
brand String // Бренд
|
||||
article String // Артикул
|
||||
price Float? // Цена (может отсутствовать)
|
||||
currency String? // Валюта
|
||||
image String? // URL изображения
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
// Уникальность по клиенту и комбинации идентификаторов товара
|
||||
@@unique([clientId, productId, offerKey, article, brand])
|
||||
@@map("favorites")
|
||||
}
|
||||
|
||||
model ClientProfile {
|
||||
id String @id @default(cuid())
|
||||
code String @unique
|
||||
name String @unique
|
||||
description String?
|
||||
baseMarkup Float @default(0)
|
||||
autoSendInvoice Boolean @default(true)
|
||||
vinRequestModule Boolean @default(false)
|
||||
clients Client[]
|
||||
|
||||
// Связи с дополнительными настройками
|
||||
priceRangeMarkups ProfilePriceRangeMarkup[]
|
||||
orderDiscounts ProfileOrderDiscount[]
|
||||
supplierMarkups ProfileSupplierMarkup[]
|
||||
brandMarkups ProfileBrandMarkup[]
|
||||
categoryMarkups ProfileCategoryMarkup[]
|
||||
excludedBrands ProfileExcludedBrand[]
|
||||
excludedCategories ProfileExcludedCategory[]
|
||||
paymentTypes ProfilePaymentType[]
|
||||
discountProfiles DiscountProfile[]
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@map("client_profiles")
|
||||
}
|
||||
|
||||
// Наценки от стоимости товара
|
||||
model ProfilePriceRangeMarkup {
|
||||
id String @id @default(cuid())
|
||||
profileId String
|
||||
profile ClientProfile @relation(fields: [profileId], references: [id], onDelete: Cascade)
|
||||
priceFrom Float
|
||||
priceTo Float
|
||||
markupType MarkupType @default(PERCENTAGE)
|
||||
markupValue Float
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
@@map("profile_price_range_markups")
|
||||
}
|
||||
|
||||
// Скидки от суммы заказа
|
||||
model ProfileOrderDiscount {
|
||||
id String @id @default(cuid())
|
||||
profileId String
|
||||
profile ClientProfile @relation(fields: [profileId], references: [id], onDelete: Cascade)
|
||||
minOrderSum Float
|
||||
discountType DiscountType @default(PERCENTAGE)
|
||||
discountValue Float
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
@@map("profile_order_discounts")
|
||||
}
|
||||
|
||||
// Наценки на поставщиков
|
||||
model ProfileSupplierMarkup {
|
||||
id String @id @default(cuid())
|
||||
profileId String
|
||||
profile ClientProfile @relation(fields: [profileId], references: [id], onDelete: Cascade)
|
||||
supplierName String
|
||||
markupType MarkupType @default(PERCENTAGE)
|
||||
markupValue Float
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
@@map("profile_supplier_markups")
|
||||
}
|
||||
|
||||
// Наценки на бренды
|
||||
model ProfileBrandMarkup {
|
||||
id String @id @default(cuid())
|
||||
profileId String
|
||||
profile ClientProfile @relation(fields: [profileId], references: [id], onDelete: Cascade)
|
||||
brandName String
|
||||
markupType MarkupType @default(PERCENTAGE)
|
||||
markupValue Float
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
@@map("profile_brand_markups")
|
||||
}
|
||||
|
||||
// Наценки на категории товаров
|
||||
model ProfileCategoryMarkup {
|
||||
id String @id @default(cuid())
|
||||
profileId String
|
||||
profile ClientProfile @relation(fields: [profileId], references: [id], onDelete: Cascade)
|
||||
categoryName String
|
||||
markupType MarkupType @default(PERCENTAGE)
|
||||
markupValue Float
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
@@map("profile_category_markups")
|
||||
}
|
||||
|
||||
// Исключенные бренды
|
||||
model ProfileExcludedBrand {
|
||||
id String @id @default(cuid())
|
||||
profileId String
|
||||
profile ClientProfile @relation(fields: [profileId], references: [id], onDelete: Cascade)
|
||||
brandName String
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
@@map("profile_excluded_brands")
|
||||
}
|
||||
|
||||
// Исключенные категории
|
||||
model ProfileExcludedCategory {
|
||||
id String @id @default(cuid())
|
||||
profileId String
|
||||
profile ClientProfile @relation(fields: [profileId], references: [id], onDelete: Cascade)
|
||||
categoryName String
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
@@map("profile_excluded_categories")
|
||||
}
|
||||
|
||||
// Типы платежей для профиля
|
||||
model ProfilePaymentType {
|
||||
id String @id @default(cuid())
|
||||
profileId String
|
||||
profile ClientProfile @relation(fields: [profileId], references: [id], onDelete: Cascade)
|
||||
paymentType PaymentType
|
||||
isEnabled Boolean @default(true)
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
@@map("profile_payment_types")
|
||||
}
|
||||
|
||||
enum MarkupType {
|
||||
PERCENTAGE // Процентная наценка
|
||||
FIXED_AMOUNT // Фиксированная сумма
|
||||
}
|
||||
|
||||
enum PaymentType {
|
||||
CASH // Наличные
|
||||
CARD // Банковская карта
|
||||
BANK_TRANSFER // Банковский перевод
|
||||
ONLINE // Онлайн платежи
|
||||
CREDIT // В кредит
|
||||
}
|
||||
|
||||
model ClientVehicle {
|
||||
id String @id @default(cuid())
|
||||
clientId String
|
||||
client Client @relation(fields: [clientId], references: [id], onDelete: Cascade)
|
||||
name String // Название авто
|
||||
vin String?
|
||||
frame String?
|
||||
licensePlate String?
|
||||
brand String?
|
||||
model String?
|
||||
modification String?
|
||||
year Int?
|
||||
mileage Int?
|
||||
comment String?
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
@@map("client_vehicles")
|
||||
}
|
||||
|
||||
// История поиска запчастей
|
||||
model PartsSearchHistory {
|
||||
id String @id @default(cuid())
|
||||
clientId String
|
||||
client Client @relation(fields: [clientId], references: [id], onDelete: Cascade)
|
||||
searchQuery String // Поисковый запрос
|
||||
searchType SearchType // Тип поиска
|
||||
brand String? // Бренд (если искали по бренду)
|
||||
articleNumber String? // Артикул (если искали по артикулу)
|
||||
|
||||
// Информация об автомобиле (если поиск был для конкретного авто)
|
||||
vehicleBrand String?
|
||||
vehicleModel String?
|
||||
vehicleYear Int?
|
||||
|
||||
resultCount Int @default(0) // Количество найденных результатов
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
@@map("parts_search_history")
|
||||
}
|
||||
|
||||
enum SearchType {
|
||||
TEXT // Текстовый поиск
|
||||
ARTICLE // Поиск по артикулу
|
||||
OEM // Поиск по OEM номеру
|
||||
VIN // Поиск автомобиля по VIN/Frame
|
||||
PLATE // Поиск автомобиля по госномеру
|
||||
WIZARD // Поиск автомобиля по параметрам
|
||||
PART_VEHICLES // Поиск автомобилей по артикулу детали
|
||||
}
|
||||
|
||||
// Адреса доставки
|
||||
model ClientDeliveryAddress {
|
||||
id String @id @default(cuid())
|
||||
clientId String
|
||||
client Client @relation(fields: [clientId], references: [id], onDelete: Cascade)
|
||||
name String // Название адреса
|
||||
address String // Полный адрес
|
||||
deliveryType DeliveryType @default(COURIER)
|
||||
comment String?
|
||||
// Дополнительные поля для курьерской доставки
|
||||
entrance String? // Подъезд
|
||||
floor String? // Этаж
|
||||
apartment String? // Квартира/офис
|
||||
intercom String? // Домофон
|
||||
deliveryTime String? // Желаемое время доставки
|
||||
contactPhone String? // Контактный телефон
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@map("client_delivery_addresses")
|
||||
}
|
||||
|
||||
// Контакты
|
||||
model ClientContact {
|
||||
id String @id @default(cuid())
|
||||
clientId String
|
||||
client Client @relation(fields: [clientId], references: [id], onDelete: Cascade)
|
||||
phone String?
|
||||
email String?
|
||||
comment String?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@map("client_contacts")
|
||||
}
|
||||
|
||||
// Договоры
|
||||
model ClientContract {
|
||||
id String @id @default(cuid())
|
||||
clientId String
|
||||
client Client @relation(fields: [clientId], references: [id], onDelete: Cascade)
|
||||
contractNumber String
|
||||
contractDate DateTime
|
||||
name String
|
||||
ourLegalEntity String // Наше ЮЛ
|
||||
clientLegalEntity String // ЮЛ клиента
|
||||
balance Float @default(0)
|
||||
currency String @default("RUB")
|
||||
isActive Boolean @default(true)
|
||||
isDefault Boolean @default(false)
|
||||
contractType String // Тип договора
|
||||
relationship String // Отношение
|
||||
paymentDelay Boolean @default(false)
|
||||
creditLimit Float?
|
||||
delayDays Int?
|
||||
fileUrl String? // Ссылка на файл договора
|
||||
balanceInvoices BalanceInvoice[] // Счета на пополнение баланса
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@map("client_contracts")
|
||||
}
|
||||
|
||||
// Счета на пополнение баланса
|
||||
model BalanceInvoice {
|
||||
id String @id @default(cuid())
|
||||
contractId String
|
||||
contract ClientContract @relation(fields: [contractId], references: [id], onDelete: Cascade)
|
||||
amount Float
|
||||
currency String @default("RUB")
|
||||
status InvoiceStatus @default(PENDING)
|
||||
invoiceNumber String @unique
|
||||
qrCode String // QR код для оплаты
|
||||
pdfUrl String? // Ссылка на PDF счета
|
||||
paymentUrl String? // Ссылка на оплату
|
||||
expiresAt DateTime // Срок действия счета
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@map("balance_invoices")
|
||||
}
|
||||
|
||||
enum InvoiceStatus {
|
||||
PENDING // Ожидает оплаты
|
||||
PAID // Оплачен
|
||||
EXPIRED // Просрочен
|
||||
CANCELLED // Отменен
|
||||
}
|
||||
|
||||
// Юридические лица клиента
|
||||
model ClientLegalEntity {
|
||||
id String @id @default(cuid())
|
||||
clientId String
|
||||
client Client @relation(fields: [clientId], references: [id], onDelete: Cascade)
|
||||
shortName String // Короткое наименование
|
||||
fullName String // Полное наименование
|
||||
form String // Форма (ООО, ИП и т.д.)
|
||||
legalAddress String // Юридический адрес
|
||||
actualAddress String? // Фактический адрес
|
||||
taxSystem String // Система налогообложения
|
||||
responsiblePhone String? // Телефон ответственного
|
||||
responsiblePosition String? // Должность ответственного
|
||||
responsibleName String? // ФИО ответственного
|
||||
accountant String? // Бухгалтер
|
||||
signatory String? // Подписант
|
||||
registrationReasonCode String? // Код причины постановки на учет
|
||||
ogrn String? // ОГРН
|
||||
inn String // ИНН
|
||||
vatPercent Float @default(20) // НДС в процентах
|
||||
bankDetails ClientBankDetails[] // Банковские реквизиты
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@map("client_legal_entities")
|
||||
}
|
||||
|
||||
// Банковские реквизиты
|
||||
model ClientBankDetails {
|
||||
id String @id @default(cuid())
|
||||
clientId String
|
||||
client Client @relation(fields: [clientId], references: [id], onDelete: Cascade)
|
||||
legalEntityId String?
|
||||
legalEntity ClientLegalEntity? @relation(fields: [legalEntityId], references: [id])
|
||||
name String // Название реквизитов
|
||||
accountNumber String // Расчетный счет
|
||||
bankName String // Наименование банка
|
||||
bik String // БИК
|
||||
correspondentAccount String // Корреспондентский счет
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@map("client_bank_details")
|
||||
}
|
||||
|
||||
// История изменения баланса
|
||||
model ClientBalanceHistory {
|
||||
id String @id @default(cuid())
|
||||
clientId String
|
||||
client Client @relation(fields: [clientId], references: [id], onDelete: Cascade)
|
||||
userId String?
|
||||
user User? @relation(fields: [userId], references: [id], onDelete: SetNull)
|
||||
oldValue Float
|
||||
newValue Float
|
||||
comment String?
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
@@map("client_balance_history")
|
||||
}
|
||||
|
||||
model ClientDiscount {
|
||||
id String @id @default(cuid())
|
||||
clientId String
|
||||
client Client @relation(fields: [clientId], references: [id], onDelete: Cascade)
|
||||
name String
|
||||
type DiscountType
|
||||
value Float // процент или фиксированная сумма
|
||||
isActive Boolean @default(true)
|
||||
validFrom DateTime?
|
||||
validTo DateTime?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@map("client_discounts")
|
||||
}
|
||||
|
||||
model ClientStatus {
|
||||
id String @id @default(cuid())
|
||||
name String @unique
|
||||
color String @default("#6B7280")
|
||||
description String?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@map("client_statuses")
|
||||
}
|
||||
|
||||
enum ClientType {
|
||||
INDIVIDUAL // Физическое лицо
|
||||
LEGAL_ENTITY // Юридическое лицо
|
||||
}
|
||||
|
||||
enum DiscountType {
|
||||
PERCENTAGE // Процентная скидка
|
||||
FIXED_AMOUNT // Фиксированная сумма
|
||||
}
|
||||
|
||||
// Модели для скидок и промокодов
|
||||
model Discount {
|
||||
id String @id @default(cuid())
|
||||
name String
|
||||
type DiscountCodeType @default(DISCOUNT)
|
||||
code String? @unique // Промокод (если есть)
|
||||
minOrderAmount Float? @default(0)
|
||||
discountType DiscountType @default(PERCENTAGE)
|
||||
discountValue Float
|
||||
isActive Boolean @default(true)
|
||||
validFrom DateTime?
|
||||
validTo DateTime?
|
||||
|
||||
// Связи с профилями
|
||||
profiles DiscountProfile[]
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@map("discounts")
|
||||
}
|
||||
|
||||
// Связь скидок с профилями клиентов
|
||||
model DiscountProfile {
|
||||
id String @id @default(cuid())
|
||||
discountId String
|
||||
discount Discount @relation(fields: [discountId], references: [id], onDelete: Cascade)
|
||||
profileId String
|
||||
profile ClientProfile @relation(fields: [profileId], references: [id], onDelete: Cascade)
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
@@unique([discountId, profileId])
|
||||
@@map("discount_profiles")
|
||||
}
|
||||
|
||||
enum DiscountCodeType {
|
||||
DISCOUNT // Обычная скидка
|
||||
PROMOCODE // Промокод
|
||||
}
|
||||
|
||||
enum DeliveryType {
|
||||
COURIER // Курьер
|
||||
PICKUP // Самовывоз
|
||||
POST // Почта России
|
||||
TRANSPORT // Транспортная компания
|
||||
}
|
||||
|
||||
// Модели для заказов и платежей
|
||||
model Order {
|
||||
id String @id @default(cuid())
|
||||
orderNumber String @unique
|
||||
clientId String?
|
||||
client Client? @relation(fields: [clientId], references: [id], onDelete: SetNull)
|
||||
clientEmail String? // Для гостевых заказов
|
||||
clientPhone String? // Для гостевых заказов
|
||||
clientName String? // Для гостевых заказов
|
||||
status OrderStatus @default(PENDING)
|
||||
totalAmount Float
|
||||
discountAmount Float @default(0)
|
||||
finalAmount Float // totalAmount - discountAmount
|
||||
currency String @default("RUB")
|
||||
items OrderItem[]
|
||||
payments Payment[]
|
||||
deliveryAddress String?
|
||||
comment String?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@map("orders")
|
||||
}
|
||||
|
||||
model OrderItem {
|
||||
id String @id @default(cuid())
|
||||
orderId String
|
||||
order Order @relation(fields: [orderId], references: [id], onDelete: Cascade)
|
||||
productId String? // Для внутренних товаров
|
||||
product Product? @relation(fields: [productId], references: [id], onDelete: SetNull)
|
||||
|
||||
// Для внешних товаров (AutoEuro)
|
||||
externalId String? // ID товара во внешней системе
|
||||
name String // Название товара
|
||||
article String? // Артикул
|
||||
brand String? // Бренд
|
||||
price Float // Цена за единицу
|
||||
quantity Int // Количество
|
||||
totalPrice Float // price * quantity
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
@@map("order_items")
|
||||
}
|
||||
|
||||
model Payment {
|
||||
id String @id @default(cuid())
|
||||
orderId String
|
||||
order Order @relation(fields: [orderId], references: [id], onDelete: Cascade)
|
||||
yookassaPaymentId String @unique // ID платежа в YooKassa
|
||||
status PaymentStatus @default(PENDING)
|
||||
amount Float
|
||||
currency String @default("RUB")
|
||||
paymentMethod String? // Способ оплаты
|
||||
description String?
|
||||
confirmationUrl String? // URL для подтверждения платежа
|
||||
|
||||
// Метаданные от YooKassa
|
||||
metadata Json?
|
||||
|
||||
// Даты
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
paidAt DateTime? // Дата успешной оплаты
|
||||
canceledAt DateTime? // Дата отмены
|
||||
|
||||
@@map("payments")
|
||||
}
|
||||
|
||||
enum OrderStatus {
|
||||
PENDING // Ожидает оплаты
|
||||
PAID // Оплачен
|
||||
PROCESSING // В обработке
|
||||
SHIPPED // Отправлен
|
||||
DELIVERED // Доставлен
|
||||
CANCELED // Отменен
|
||||
REFUNDED // Возвращен
|
||||
}
|
||||
|
||||
enum PaymentStatus {
|
||||
PENDING // Ожидает оплаты
|
||||
WAITING_FOR_CAPTURE // Ожидает подтверждения
|
||||
SUCCEEDED // Успешно оплачен
|
||||
CANCELED // Отменен
|
||||
REFUNDED // Возвращен
|
||||
}
|
Reference in New Issue
Block a user