feat: реализовать V2 backend для товарных поставок селлера
- Создать модели: SellerGoodsSupplyOrder, SellerGoodsInventory, GoodsSupplyRecipeItem - Реализовать полные GraphQL resolvers с валидацией и авторизацией - Добавить автоматическое создание инвентаря при статусе DELIVERED - Внедрить нормализованную рецептуру с RecipeType enum - Подготовить функции для будущих отгрузок на маркетплейсы - Интегрировать V2 resolvers модульно в основную схему - Протестировать создание таблиц в БД 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@ -27,6 +27,7 @@ model User {
|
||||
// === НОВЫЕ СВЯЗИ С ПРИЕМКОЙ ПОСТАВОК V2 ===
|
||||
fulfillmentSupplyOrdersReceived FulfillmentConsumableSupplyOrder[] @relation("FFSupplyOrdersReceiver")
|
||||
sellerSupplyOrdersReceived SellerConsumableSupplyOrder[] @relation("SellerSupplyOrdersReceiver")
|
||||
sellerGoodsSupplyOrdersReceived SellerGoodsSupplyOrder[] @relation("SellerGoodsSupplyOrdersReceiver")
|
||||
|
||||
@@map("users")
|
||||
}
|
||||
@ -143,6 +144,16 @@ model Organization {
|
||||
// === СВЯЗИ С ИНВЕНТАРЕМ РАСХОДНИКОВ СЕЛЛЕРА V2 ===
|
||||
sellerInventoryAsOwner SellerConsumableInventory[] @relation("SellerInventory")
|
||||
sellerInventoryAsWarehouse SellerConsumableInventory[] @relation("SellerInventoryWarehouse")
|
||||
|
||||
// === СВЯЗИ С ТОВАРНЫМИ ПОСТАВКАМИ СЕЛЛЕРА V2 ===
|
||||
sellerGoodsSupplyOrdersAsSeller SellerGoodsSupplyOrder[] @relation("SellerGoodsSupplyOrdersSeller")
|
||||
sellerGoodsSupplyOrdersAsFulfillment SellerGoodsSupplyOrder[] @relation("SellerGoodsSupplyOrdersFulfillment")
|
||||
sellerGoodsSupplyOrdersAsSupplier SellerGoodsSupplyOrder[] @relation("SellerGoodsSupplyOrdersSupplier")
|
||||
sellerGoodsSupplyOrdersAsLogistics SellerGoodsSupplyOrder[] @relation("SellerGoodsSupplyOrdersLogistics")
|
||||
|
||||
// === СВЯЗИ С ИНВЕНТАРЕМ ТОВАРОВ СЕЛЛЕРА V2 ===
|
||||
sellerGoodsInventoryAsOwner SellerGoodsInventory[] @relation("SellerGoodsInventoryOwner")
|
||||
sellerGoodsInventoryAsWarehouse SellerGoodsInventory[] @relation("SellerGoodsInventoryWarehouse")
|
||||
|
||||
@@index([referralCode])
|
||||
@@index([referredById])
|
||||
@ -314,6 +325,10 @@ model Product {
|
||||
// === НОВЫЕ СВЯЗИ СО СКЛАДСКИМИ ОСТАТКАМИ V2 ===
|
||||
inventoryRecords FulfillmentConsumableInventory[] @relation("InventoryProducts")
|
||||
sellerInventoryRecords SellerConsumableInventory[] @relation("SellerInventoryProducts")
|
||||
|
||||
// === СВЯЗИ С ТОВАРНЫМИ ПОСТАВКАМИ V2 ===
|
||||
goodsSupplyRecipeItems GoodsSupplyRecipeItem[] @relation("GoodsSupplyRecipeItems")
|
||||
sellerGoodsInventoryRecords SellerGoodsInventory[] @relation("SellerGoodsInventoryProduct")
|
||||
|
||||
@@unique([organizationId, article])
|
||||
@@map("products")
|
||||
@ -1043,3 +1058,126 @@ model SellerConsumableInventory {
|
||||
@@index([sellerId, lastSupplyDate])
|
||||
@@map("seller_consumable_inventory")
|
||||
}
|
||||
|
||||
// ===============================================
|
||||
// 🛒 SELLER GOODS SUPPLY SYSTEM V2.0 - ТОВАРНЫЕ ПОСТАВКИ
|
||||
// ===============================================
|
||||
|
||||
// Модель для поставок товаров селлера (V2)
|
||||
model SellerGoodsSupplyOrder {
|
||||
// === БАЗОВЫЕ ПОЛЯ ===
|
||||
id String @id @default(cuid())
|
||||
status SellerSupplyOrderStatus @default(PENDING)
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
// === ДАННЫЕ СЕЛЛЕРА (создатель) ===
|
||||
sellerId String // кто заказывает (FK: Organization SELLER)
|
||||
fulfillmentCenterId String // куда доставлять (FK: Organization FULFILLMENT)
|
||||
requestedDeliveryDate DateTime // когда нужно
|
||||
notes String? // заметки селлера
|
||||
|
||||
// === ДАННЫЕ ПОСТАВЩИКА ===
|
||||
supplierId String? // кто поставляет (FK: Organization WHOLESALE)
|
||||
supplierApprovedAt DateTime? // когда одобрил
|
||||
packagesCount Int? // количество грузомест
|
||||
estimatedVolume Decimal? @db.Decimal(8, 3) // объем груза в м³
|
||||
supplierContractId String? // номер договора
|
||||
supplierNotes String? // заметки поставщика
|
||||
|
||||
// === ДАННЫЕ ЛОГИСТИКИ ===
|
||||
logisticsPartnerId String? // кто везет (FK: Organization LOGIST)
|
||||
estimatedDeliveryDate DateTime? // план доставки
|
||||
routeId String? // маршрут (FK: LogisticsRoute)
|
||||
logisticsCost Decimal? @db.Decimal(10, 2) // стоимость доставки
|
||||
logisticsNotes String? // заметки логистики
|
||||
|
||||
// === ДАННЫЕ ОТГРУЗКИ ===
|
||||
shippedAt DateTime? // факт отгрузки
|
||||
trackingNumber String? // номер отслеживания
|
||||
|
||||
// === ДАННЫЕ ПОЛУЧЕНИЯ ===
|
||||
deliveredAt DateTime? // факт доставки
|
||||
receivedById String? // кто принял (FK: User)
|
||||
receiptNotes String? // заметки при получении
|
||||
|
||||
// === ФИНАНСЫ ===
|
||||
totalCostWithDelivery Decimal @default(0) @db.Decimal(12, 2) // общая стоимость с доставкой
|
||||
actualDeliveryCost Decimal @default(0) @db.Decimal(10, 2) // фактическая стоимость доставки
|
||||
|
||||
// === СВЯЗИ ===
|
||||
seller Organization @relation("SellerGoodsSupplyOrdersSeller", fields: [sellerId], references: [id])
|
||||
fulfillmentCenter Organization @relation("SellerGoodsSupplyOrdersFulfillment", fields: [fulfillmentCenterId], references: [id])
|
||||
supplier Organization? @relation("SellerGoodsSupplyOrdersSupplier", fields: [supplierId], references: [id])
|
||||
logisticsPartner Organization? @relation("SellerGoodsSupplyOrdersLogistics", fields: [logisticsPartnerId], references: [id])
|
||||
receivedBy User? @relation("SellerGoodsSupplyOrdersReceiver", fields: [receivedById], references: [id])
|
||||
recipeItems GoodsSupplyRecipeItem[] // нормализованная рецептура товаров
|
||||
|
||||
@@map("seller_goods_supply_orders")
|
||||
}
|
||||
|
||||
// Нормализованная рецептура для товарных поставок
|
||||
model GoodsSupplyRecipeItem {
|
||||
id String @id @default(cuid())
|
||||
supplyOrderId String // связь с поставкой (FK: SellerGoodsSupplyOrder)
|
||||
productId String // какой товар (FK: Product)
|
||||
quantity Int // количество в рецептуре
|
||||
recipeType RecipeType // тип компонента в рецептуре
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
// === СВЯЗИ ===
|
||||
supplyOrder SellerGoodsSupplyOrder @relation(fields: [supplyOrderId], references: [id], onDelete: Cascade)
|
||||
product Product @relation("GoodsSupplyRecipeItems", fields: [productId], references: [id])
|
||||
|
||||
@@unique([supplyOrderId, productId]) // один товар = одна запись в рецептуре
|
||||
@@map("goods_supply_recipe_items")
|
||||
}
|
||||
|
||||
// Enum для типов компонентов в рецептуре
|
||||
enum RecipeType {
|
||||
MAIN_PRODUCT // Основной товар
|
||||
COMPONENT // Компонент товара
|
||||
PACKAGING // Упаковка
|
||||
ACCESSORY // Аксессуар
|
||||
}
|
||||
|
||||
// Инвентарь товаров селлера на складе фулфилмента (V2)
|
||||
model SellerGoodsInventory {
|
||||
// === ИДЕНТИФИКАЦИЯ ===
|
||||
id String @id @default(cuid())
|
||||
|
||||
// === СВЯЗИ ===
|
||||
sellerId String // кому принадлежат товары (FK: Organization SELLER)
|
||||
fulfillmentCenterId String // где хранятся (FK: Organization FULFILLMENT)
|
||||
productId String // что хранится (FK: Product)
|
||||
|
||||
// === СКЛАДСКИЕ ДАННЫЕ ===
|
||||
currentStock Int @default(0) // текущий остаток на складе фулфилмента
|
||||
reservedStock Int @default(0) // зарезервировано для отгрузок
|
||||
inPreparationStock Int @default(0) // в подготовке к отгрузке
|
||||
totalReceived Int @default(0) // всего получено с момента создания
|
||||
totalShipped Int @default(0) // всего отгружено
|
||||
|
||||
// === ПОРОГИ ДЛЯ АВТОЗАКАЗА ===
|
||||
minStock Int @default(0) // минимальный порог для автозаказа
|
||||
maxStock Int? // максимальный порог (опционально)
|
||||
|
||||
// === ЦЕНЫ ===
|
||||
averageCost Decimal @default(0) @db.Decimal(10, 2) // средняя себестоимость покупки
|
||||
salePrice Decimal @default(0) @db.Decimal(10, 2) // цена продажи
|
||||
|
||||
// === МЕТАДАННЫЕ ===
|
||||
lastSupplyDate DateTime? // последняя поставка
|
||||
lastShipDate DateTime? // последняя отгрузка
|
||||
notes String? // заметки по складскому учету
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
// === СВЯЗИ ===
|
||||
seller Organization @relation("SellerGoodsInventoryOwner", fields: [sellerId], references: [id])
|
||||
fulfillmentCenter Organization @relation("SellerGoodsInventoryWarehouse", fields: [fulfillmentCenterId], references: [id])
|
||||
product Product @relation("SellerGoodsInventoryProduct", fields: [productId], references: [id])
|
||||
|
||||
@@unique([sellerId, fulfillmentCenterId, productId]) // уникальность: селлер + фф + товар
|
||||
@@map("seller_goods_inventory")
|
||||
}
|
||||
|
Reference in New Issue
Block a user