799 lines
26 KiB
Plaintext
799 lines
26 KiB
Plaintext
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 // Возвращен
|
||
}
|