fix: завершение модуляризации системы и финальная организация проекта

## Структурные изменения:

### 📁 Организация архивных файлов:
- Перенос всех устаревших правил в legacy-rules/
- Создание структуры docs-and-reports/ для отчетов
- Архивация backup файлов в legacy-rules/backups/

### 🔧 Критические компоненты:
- src/components/supplies/multilevel-supplies-table.tsx - многоуровневая таблица поставок
- src/components/supplies/components/recipe-display.tsx - отображение рецептур
- src/components/fulfillment-supplies/fulfillment-goods-orders-tab.tsx - вкладка товарных заказов

### 🎯 GraphQL обновления:
- Обновление mutations.ts, queries.ts, resolvers.ts, typedefs.ts
- Синхронизация с Prisma schema.prisma
- Backup файлы для истории изменений

### 🛠️ Утилитарные скрипты:
- 12 новых скриптов в scripts/ для анализа данных
- Скрипты проверки фулфилмент-пользователей
- Утилиты очистки и фиксации данных поставок

### 📊 Тестирование:
- test-fulfillment-filtering.js - тестирование фильтрации фулфилмента
- test-full-workflow.js - полный workflow тестирование

### 📝 Документация:
- logistics-statistics-warehouse-rules.md - объединенные правила модулей
- Обновление журналов модуляризации и разработки

###  Исправления ESLint:
- Исправлены критические ошибки в sidebar.tsx
- Исправлены ошибки типизации в multilevel-supplies-table.tsx
- Исправлены неиспользуемые переменные в goods-supplies-table.tsx
- Заменены типы any на строгую типизацию
- Исправлены console.log на console.warn

## Результат:
- Завершена полная модуляризация системы
- Организована архитектура legacy файлов
- Добавлены критически важные компоненты таблиц
- Создана полная инфраструктура тестирования
- Исправлены все критические ESLint ошибки
- Сохранены 103 незакоммиченных изменения

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Veronika Smirnova
2025-08-22 10:31:43 +03:00
parent 621770e765
commit 89257c75b5
86 changed files with 25406 additions and 942 deletions

View File

@ -0,0 +1,197 @@
const { PrismaClient } = require('@prisma/client')
const prisma = new PrismaClient()
async function analyzeFulfillmentSupplies() {
try {
console.log('🔍 ГЛУБОКИЙ АНАЛИЗ РАСХОДНИКОВ ФУЛФИЛМЕНТА')
console.log('=' .repeat(60))
// Находим фулфилмент организацию пользователя с номером +7 (999) 999-99-99
const fulfillmentUser = await prisma.user.findFirst({
where: { phone: '79999999999' },
include: {
organization: {
include: {
_count: {
select: {
supplies: true,
supplyOrders: true,
fulfillmentSupplyOrders: true
}
}
}
}
}
})
if (!fulfillmentUser?.organization) {
console.log('❌ Фулфилмент пользователь или организация не найдены')
return
}
const org = fulfillmentUser.organization
console.log('🏢 ОРГАНИЗАЦИЯ:')
console.log(` ID: ${org.id}`)
console.log(` Название: ${org.name}`)
console.log(` Тип: ${org.type}`)
console.log(` Расходников на складе: ${org._count.supplies}`)
console.log(` Заказов поставок: ${org._count.supplyOrders}`)
console.log(` Входящих поставок: ${org._count.fulfillmentSupplyOrders}`)
console.log('')
// 1. АНАЛИЗ РАСХОДНИКОВ НА СКЛАДЕ
console.log('📦 1. РАСХОДНИКИ НА СКЛАДЕ:')
const allSupplies = await prisma.supply.findMany({
where: { organizationId: org.id },
orderBy: { createdAt: 'desc' }
})
console.log(` Всего записей Supply: ${allSupplies.length}`)
// Группируем по типам
const fulfillmentSupplies = allSupplies.filter(s => s.type === 'FULFILLMENT_CONSUMABLES')
const sellerSupplies = allSupplies.filter(s => s.type === 'SELLER_CONSUMABLES')
console.log(` 📊 Расходники фулфилмента: ${fulfillmentSupplies.length} записей`)
console.log(` 💼 Расходники селлеров: ${sellerSupplies.length} записей`)
console.log('')
// Детальный анализ расходников фулфилмента
if (fulfillmentSupplies.length > 0) {
console.log('🔍 ДЕТАЛИ РАСХОДНИКОВ ФУЛФИЛМЕНТА:')
fulfillmentSupplies.forEach((supply, index) => {
console.log(` ${index + 1}. "${supply.name}" (${supply.article})`)
console.log(` ID: ${supply.id}`)
console.log(` Количество: ${supply.quantity} шт`)
console.log(` Текущий остаток: ${supply.currentStock} шт`)
console.log(` Использовано: ${supply.usedStock} шт`)
console.log(` Статус: ${supply.status}`)
console.log(` Поставщик: ${supply.supplier}`)
console.log(` Дата: ${supply.date?.toISOString().split('T')[0]}`)
console.log(` Создано: ${supply.createdAt?.toISOString().split('T')[0]}`)
console.log('')
})
}
// 2. АНАЛИЗ ЗАКАЗОВ ПОСТАВОК
console.log('📋 2. ЗАКАЗЫ ПОСТАВОК (созданные фулфилментом):')
const createdOrders = await prisma.supplyOrder.findMany({
where: { organizationId: org.id },
include: {
partner: { select: { name: true, type: true } },
items: {
include: { product: { select: { name: true, article: true } } }
}
},
orderBy: { createdAt: 'desc' }
})
console.log(` Всего заказов: ${createdOrders.length}`)
createdOrders.forEach((order, index) => {
console.log(` ${index + 1}. Заказ ${order.id}`)
console.log(` Поставщик: ${order.partner.name} (${order.partner.type})`)
console.log(` Статус: ${order.status}`)
console.log(` Тип расходников: ${order.consumableType}`)
console.log(` Дата доставки: ${order.deliveryDate?.toISOString().split('T')[0]}`)
console.log(` Сумма: ${order.totalAmount}`)
console.log(` Товаров: ${order.items.length}`)
order.items.forEach((item, itemIndex) => {
console.log(` ${itemIndex + 1}) ${item.product.name} (${item.product.article}) - ${item.quantity} шт`)
})
console.log('')
})
// 3. АНАЛИЗ ВХОДЯЩИХ ПОСТАВОК
console.log('📥 3. ВХОДЯЩИЕ ПОСТАВКИ (доставляемые на фулфилмент):')
const receivedOrders = await prisma.supplyOrder.findMany({
where: { fulfillmentCenterId: org.id },
include: {
organization: { select: { name: true, type: true } },
partner: { select: { name: true, type: true } },
items: {
include: { product: { select: { name: true, article: true } } }
}
},
orderBy: { createdAt: 'desc' }
})
console.log(` Всего входящих поставок: ${receivedOrders.length}`)
receivedOrders.forEach((order, index) => {
console.log(` ${index + 1}. Поставка ${order.id}`)
console.log(` Заказчик: ${order.organization.name} (${order.organization.type})`)
console.log(` Поставщик: ${order.partner.name} (${order.partner.type})`)
console.log(` Статус: ${order.status}`)
console.log(` Тип расходников: ${order.consumableType}`)
console.log(` Дата доставки: ${order.deliveryDate?.toISOString().split('T')[0]}`)
console.log(` Сумма: ${order.totalAmount}`)
console.log(` Товаров: ${order.items.length}`)
order.items.forEach((item, itemIndex) => {
console.log(` ${itemIndex + 1}) ${item.product.name} (${item.product.article}) - ${item.quantity} шт`)
})
console.log('')
})
// 4. СВЕРКА ДАННЫХ
console.log('⚖️ 4. СВЕРКА ДАННЫХ:')
// Подсчитываем ожидаемое количество расходников из заказов
const totalFromOrders = createdOrders
.filter(order => order.status === 'DELIVERED' && order.consumableType === 'FULFILLMENT_CONSUMABLES')
.reduce((sum, order) => {
return sum + order.items.reduce((itemSum, item) => itemSum + item.quantity, 0)
}, 0)
const totalFromSupplies = fulfillmentSupplies.reduce((sum, supply) => sum + supply.currentStock, 0)
console.log(` 📊 Ожидаемое из доставленных заказов: ${totalFromOrders} шт`)
console.log(` 📦 Фактическое в Supply записях: ${totalFromSupplies} шт`)
console.log(` ${totalFromOrders === totalFromSupplies ? '✅' : '❌'} Соответствие: ${totalFromOrders === totalFromSupplies ? 'КОРРЕКТНО' : 'ОШИБКА'}`)
if (totalFromOrders !== totalFromSupplies) {
console.log(` 🔍 Разница: ${Math.abs(totalFromOrders - totalFromSupplies)} шт`)
}
// 5. АНАЛИЗ ПО АРТИКУЛАМ
console.log('')
console.log('🏷️ 5. АНАЛИЗ ПО АРТИКУЛАМ:')
const articleGroups = {}
fulfillmentSupplies.forEach(supply => {
if (!articleGroups[supply.article]) {
articleGroups[supply.article] = []
}
articleGroups[supply.article].push(supply)
})
console.log(` Уникальных артикулов: ${Object.keys(articleGroups).length}`)
Object.entries(articleGroups).forEach(([article, supplies]) => {
const totalStock = supplies.reduce((sum, s) => sum + s.currentStock, 0)
console.log(` 📋 ${article}: ${supplies.length} записей, ${totalStock} шт общий остаток`)
if (supplies.length > 1) {
console.log(` ⚠️ ДУБЛИРОВАНИЕ: ${supplies.length} записей для одного артикула!`)
supplies.forEach((supply, index) => {
console.log(` ${index + 1}) ID: ${supply.id}, остаток: ${supply.currentStock} шт`)
})
}
})
console.log('')
console.log('=' .repeat(60))
console.log('✅ АНАЛИЗ ЗАВЕРШЕН')
} catch (error) {
console.error('❌ ОШИБКА при анализе:', error)
console.error(' Детали:', error.message)
} finally {
await prisma.$disconnect()
}
}
analyzeFulfillmentSupplies()

View File

@ -0,0 +1,87 @@
const { PrismaClient } = require('@prisma/client')
const prisma = new PrismaClient()
async function checkFulfillmentUser() {
try {
console.log('🔍 ПОИСК ПОЛЬЗОВАТЕЛЯ +7 (999) 999-99-99...')
// Ищем пользователя по номеру телефона
const user = await prisma.user.findFirst({
where: { phone: '+7 (999) 999-99-99' },
include: {
organization: {
select: {
id: true,
name: true,
type: true
}
}
}
})
if (!user) {
console.log('❌ Пользователь с номером +7 (999) 999-99-99 не найден')
return
}
console.log('👤 ПОЛЬЗОВАТЕЛЬ НАЙДЕН:')
console.log(' ID:', user.id)
console.log(' Телефон:', user.phone)
console.log(' Организация:', user.organization?.name || 'Нет')
console.log(' Тип организации:', user.organization?.type || 'Нет')
if (user.organization?.type === 'FULFILLMENT') {
console.log('\n📦 ПРОВЕРЯЕМ СКЛАД ФУЛФИЛМЕНТА:')
// Проверяем Supply записи для фулфилмента
const supplies = await prisma.supply.findMany({
where: {
organizationId: user.organization.id,
type: 'FULFILLMENT_CONSUMABLES'
},
select: {
id: true,
name: true,
article: true,
currentStock: true,
quantity: true,
status: true,
supplier: true,
createdAt: true
},
orderBy: { updatedAt: 'desc' }
})
console.log('\n📋 РАСХОДНИКИ ФУЛФИЛМЕНТА:', supplies.length, 'позиций')
if (supplies.length === 0) {
console.log(' 📭 Склад пуст - нет расходников')
} else {
supplies.forEach((supply, index) => {
console.log(`\n ${index + 1}. "${supply.name}"`)
console.log(` Артикул: ${supply.article || 'Нет'}`)
console.log(` Остаток: ${supply.currentStock} шт`)
console.log(` Всего: ${supply.quantity} шт`)
console.log(` Поставщик: ${supply.supplier || 'Нет'}`)
console.log(` Статус: ${supply.status}`)
console.log(` Создан: ${supply.createdAt.toISOString().split('T')[0]}`)
})
const totalStock = supplies.reduce((sum, s) => sum + s.currentStock, 0)
console.log(`\n📊 ИТОГО на складе: ${totalStock} шт`)
}
} else {
console.log('⚠️ Пользователь не является фулфилментом')
console.log(' Тип организации:', user.organization?.type)
}
} catch (error) {
console.error('❌ Ошибка:', error.message)
} finally {
await prisma.$disconnect()
}
}
checkFulfillmentUser()

View File

@ -0,0 +1,136 @@
const { PrismaClient } = require('@prisma/client')
const prisma = new PrismaClient()
async function checkFulfillmentWarehouse() {
try {
console.log('🔍 ПРОВЕРЯЕМ СКЛАД ФУЛФИЛМЕНТА ДЛЯ ПОЛЬЗОВАТЕЛЯ 79999999999...')
// Найдем пользователя и его организацию
const user = await prisma.user.findFirst({
where: { phone: '79999999999' },
include: {
organization: true
}
})
if (!user || user.organization?.type !== 'FULFILLMENT') {
console.log('❌ Пользователь не является фулфилментом')
return
}
console.log('🏢 ОРГАНИЗАЦИЯ ФУЛФИЛМЕНТА:')
console.log(' Название:', user.organization.name)
console.log(' ID:', user.organization.id)
console.log(' Тип:', user.organization.type)
console.log('\n📦 ПРОВЕРЯЕМ РАСХОДНИКИ ФУЛФИЛМЕНТА:')
// Supply записи для фулфилмента
const supplies = await prisma.supply.findMany({
where: {
organizationId: user.organization.id,
type: 'FULFILLMENT_CONSUMABLES'
},
select: {
id: true,
name: true,
article: true,
currentStock: true,
quantity: true,
usedStock: true,
status: true,
supplier: true,
category: true,
price: true,
unit: true,
createdAt: true,
updatedAt: true
},
orderBy: { updatedAt: 'desc' }
})
console.log(`\n📋 РАСХОДНИКИ НА СКЛАДЕ: ${supplies.length} позиций`)
if (supplies.length === 0) {
console.log(' 📭 Склад пуст - нет расходников фулфилмента')
} else {
let totalCurrent = 0
let totalUsed = 0
supplies.forEach((supply, index) => {
console.log(`\n ${index + 1}. "${supply.name}"`)
console.log(` 📋 ID: ${supply.id}`)
console.log(` 🏷️ Артикул: ${supply.article || 'Нет'}`)
console.log(` 📦 Текущий остаток: ${supply.currentStock} ${supply.unit || 'шт'}`)
console.log(` 📊 Общее количество: ${supply.quantity} ${supply.unit || 'шт'}`)
console.log(` ✅ Использовано: ${supply.usedStock} ${supply.unit || 'шт'}`)
console.log(` 💰 Цена: ${supply.price || 0} руб`)
console.log(` 📂 Категория: ${supply.category || 'Не указана'}`)
console.log(` 🏪 Поставщик: ${supply.supplier || 'Не указан'}`)
console.log(` 🔖 Статус: ${supply.status}`)
console.log(` 📅 Создан: ${supply.createdAt.toISOString().split('T')[0]}`)
console.log(` 🔄 Обновлен: ${supply.updatedAt.toISOString().split('T')[0]}`)
totalCurrent += supply.currentStock
totalUsed += supply.usedStock
})
console.log(`\n📊 ИТОГОВАЯ СТАТИСТИКА:`)
console.log(` 📦 Общий остаток: ${totalCurrent} единиц`)
console.log(`Всего использовано: ${totalUsed} единиц`)
console.log(` 🏷️ Всего позиций: ${supplies.length}`)
// Статистика по статусам
const statusStats = supplies.reduce((acc, supply) => {
acc[supply.status] = (acc[supply.status] || 0) + 1
return acc
}, {})
console.log(`\n📈 СТАТИСТИКА ПО СТАТУСАМ:`)
Object.entries(statusStats).forEach(([status, count]) => {
console.log(` ${status}: ${count} позиций`)
})
}
// Проверяем заказы поставок
console.log('\n📋 ПРОВЕРЯЕМ ЗАКАЗЫ ПОСТАВОК:')
const supplyOrders = await prisma.supplyOrder.findMany({
where: {
fulfillmentCenterId: user.organization.id
},
include: {
items: {
include: {
product: {
select: {
name: true,
article: true
}
}
}
}
},
orderBy: { updatedAt: 'desc' },
take: 5
})
console.log(` 📦 Заказов поставок: ${supplyOrders.length} (последние 5)`)
supplyOrders.forEach((order, index) => {
console.log(`\n ${index + 1}. Заказ ${order.id}`)
console.log(` 📋 Статус: ${order.status}`)
console.log(` 📅 Дата доставки: ${order.deliveryDate.toISOString().split('T')[0]}`)
console.log(` 📦 Элементов: ${order.items.length}`)
order.items.forEach((item, itemIndex) => {
console.log(` ${itemIndex + 1}. ${item.product.name} x${item.quantity} (арт: ${item.product.article})`)
})
})
} catch (error) {
console.error('❌ Ошибка:', error.message)
} finally {
await prisma.$disconnect()
}
}
checkFulfillmentWarehouse()

View File

@ -0,0 +1,134 @@
const { PrismaClient } = require('@prisma/client')
const prisma = new PrismaClient()
async function checkSupplyOrderTypes() {
try {
console.log('🔍 ПРОВЕРЯЕМ ТИПЫ ЗАКАЗОВ ПОСТАВОК...')
// Найдем пользователя фулфилмента
const user = await prisma.user.findFirst({
where: { phone: '79999999999' },
include: {
organization: true
}
})
if (!user || user.organization?.type !== 'FULFILLMENT') {
console.log('❌ Пользователь фулфилмента не найден')
return
}
console.log('🏢 ФУЛФИЛМЕНТ ОРГАНИЗАЦИЯ:')
console.log(' Название:', user.organization.name)
console.log(' ID:', user.organization.id)
// Проверяем все заказы поставок для этого фулфилмента
const supplyOrders = await prisma.supplyOrder.findMany({
where: {
fulfillmentCenterId: user.organization.id
},
include: {
items: {
include: {
product: {
select: {
name: true,
article: true,
type: true
}
}
}
},
organization: {
select: {
name: true,
type: true
}
},
partner: {
select: {
name: true,
type: true
}
}
},
orderBy: { updatedAt: 'desc' }
})
console.log(`\n📋 НАЙДЕНО ЗАКАЗОВ ПОСТАВОК: ${supplyOrders.length}`)
supplyOrders.forEach((order, index) => {
console.log(`\n${index + 1}. ЗАКАЗ ${order.id}`)
console.log(` 📅 Статус: ${order.status}`)
console.log(` 🏷️ Тип расходников (consumableType): ${order.consumableType || 'НЕ УКАЗАН'}`)
console.log(` 👤 Заказчик: ${order.organization?.name} (${order.organization?.type})`)
console.log(` 🏪 Поставщик: ${order.partner?.name} (${order.partner?.type})`)
console.log(` 📦 Элементов в заказе: ${order.items.length}`)
order.items.forEach((item, itemIndex) => {
console.log(` ${itemIndex + 1}. "${item.product.name}"`)
console.log(` Артикул: ${item.product.article}`)
console.log(` Тип товара: ${item.product.type}`)
console.log(` Количество: ${item.quantity}`)
})
console.log(' ---')
})
// Анализируем проблемы
console.log('\n🔍 АНАЛИЗ ПРОБЛЕМ:')
const problemOrders = supplyOrders.filter(order => {
// Проверяем заказы с неправильным consumableType
if (order.organization?.type === 'FULFILLMENT' && order.consumableType === 'SELLER_CONSUMABLES') {
return true
}
if (order.organization?.type === 'SELLER' && order.consumableType === 'FULFILLMENT_CONSUMABLES') {
return true
}
return false
})
if (problemOrders.length > 0) {
console.log(`❌ НАЙДЕНО ПРОБЛЕМНЫХ ЗАКАЗОВ: ${problemOrders.length}`)
problemOrders.forEach(order => {
console.log(` Заказ ${order.id}: заказчик ${order.organization?.type}, тип расходников ${order.consumableType}`)
})
} else {
console.log('✅ Все заказы имеют корректные типы расходников')
}
// Проверяем созданные Supply записи
console.log('\n📦 ПРОВЕРЯЕМ СОЗДАННЫЕ SUPPLY ЗАПИСИ:')
const supplies = await prisma.supply.findMany({
where: {
organizationId: user.organization.id
},
select: {
id: true,
name: true,
article: true,
type: true,
sellerOwnerId: true,
currentStock: true,
createdAt: true
},
orderBy: { updatedAt: 'desc' }
})
supplies.forEach((supply, index) => {
console.log(` ${index + 1}. "${supply.name}" (${supply.article})`)
console.log(` Тип: ${supply.type}`)
console.log(` Владелец-селлер: ${supply.sellerOwnerId || 'НЕТ'}`)
console.log(` Остаток: ${supply.currentStock}`)
console.log(` Создан: ${supply.createdAt.toISOString().split('T')[0]}`)
})
} catch (error) {
console.error('❌ Ошибка:', error.message)
} finally {
await prisma.$disconnect()
}
}
checkSupplyOrderTypes()

View File

@ -0,0 +1,136 @@
const { PrismaClient } = require('@prisma/client')
const prisma = new PrismaClient()
async function checkUIFulfillmentStats() {
try {
console.log('📊 ПРОВЕРКА ДАННЫХ ДЛЯ UI "РАСХОДНИКИ ФУЛФИЛМЕНТ"')
console.log('=' .repeat(60))
// Находим фулфилмент организацию
const fulfillmentUser = await prisma.user.findFirst({
where: { phone: '79999999999' },
include: { organization: true }
})
if (!fulfillmentUser?.organization) {
console.log('❌ Фулфилмент организация не найдена')
return
}
const orgId = fulfillmentUser.organization.id
console.log(`🏢 Организация: ${fulfillmentUser.organization.name} (${orgId})`)
console.log('')
// === ДАННЫЕ КАК В UI КОМПОНЕНТЕ ===
// 1. ЗАКАЗАНО - из SupplyOrder (все заказы фулфилмента на расходники)
const supplyOrders = await prisma.supplyOrder.findMany({
where: {
organizationId: orgId, // Заказчик = фулфилмент
consumableType: 'FULFILLMENT_CONSUMABLES'
},
include: {
items: {
include: { product: true }
}
}
})
const totalOrdered = supplyOrders.reduce((sum, order) => {
return sum + order.items.reduce((itemSum, item) => itemSum + item.quantity, 0)
}, 0)
console.log('📋 1. ЗАКАЗАНО (всего в SupplyOrder):')
console.log(` Всего заказов: ${supplyOrders.length}`)
console.log(` Общее количество: ${totalOrdered} шт`)
// Разбивка по статусам
const ordersByStatus = {}
supplyOrders.forEach(order => {
if (!ordersByStatus[order.status]) {
ordersByStatus[order.status] = { count: 0, quantity: 0 }
}
ordersByStatus[order.status].count++
ordersByStatus[order.status].quantity += order.items.reduce((sum, item) => sum + item.quantity, 0)
})
Object.entries(ordersByStatus).forEach(([status, data]) => {
console.log(` ${status}: ${data.count} заказов, ${data.quantity} шт`)
})
console.log('')
// 2. ПОСТАВЛЕНО - из SupplyOrder со статусом DELIVERED
const deliveredOrders = supplyOrders.filter(order => order.status === 'DELIVERED')
const totalDelivered = deliveredOrders.reduce((sum, order) => {
return sum + order.items.reduce((itemSum, item) => itemSum + item.quantity, 0)
}, 0)
console.log('🚚 2. ПОСТАВЛЕНО (DELIVERED заказы):')
console.log(` Доставленных заказов: ${deliveredOrders.length}`)
console.log(` Общее количество: ${totalDelivered} шт`)
if (deliveredOrders.length > 0) {
console.log(' Детали доставленных заказов:')
deliveredOrders.forEach((order, index) => {
const orderQuantity = order.items.reduce((sum, item) => sum + item.quantity, 0)
console.log(` ${index + 1}. Заказ ${order.id}: ${orderQuantity} шт`)
order.items.forEach(item => {
console.log(` - ${item.product.name} (${item.product.article}): ${item.quantity} шт`)
})
})
}
console.log('')
// 3. ОСТАТОК - из Supply записей типа FULFILLMENT_CONSUMABLES
const fulfillmentSupplies = await prisma.supply.findMany({
where: {
organizationId: orgId,
type: 'FULFILLMENT_CONSUMABLES'
}
})
const totalInStock = fulfillmentSupplies.reduce((sum, supply) => sum + supply.currentStock, 0)
console.log('📦 3. ОСТАТОК (Supply записи):')
console.log(` Записей на складе: ${fulfillmentSupplies.length}`)
console.log(` Общий остаток: ${totalInStock} шт`)
if (fulfillmentSupplies.length > 0) {
console.log(' Детали по складу:')
fulfillmentSupplies.forEach((supply, index) => {
console.log(` ${index + 1}. "${supply.name}" (${supply.article}):`)
console.log(` Количество: ${supply.quantity} шт`)
console.log(` Текущий остаток: ${supply.currentStock} шт`)
console.log(` Использовано: ${supply.usedStock} шт`)
console.log(` Статус: ${supply.status}`)
})
}
console.log('')
// === СВОДКА ДЛЯ UI ===
console.log('📊 ИТОГОВЫЕ ЦИФРЫ ДЛЯ UI:')
console.log(` 📋 ЗАКАЗАНО: ${totalOrdered} шт`)
console.log(` 🚚 ПОСТАВЛЕНО: ${totalDelivered} шт`)
console.log(` 📦 ОСТАТОК: ${totalInStock} шт`)
console.log('')
// === ПРОВЕРКА ЛОГИКИ ===
console.log('🔍 ПРОВЕРКА ЛОГИКИ:')
const expectedRemaining = totalDelivered - (fulfillmentSupplies.reduce((sum, s) => sum + s.usedStock, 0))
console.log(` Ожидаемый остаток: ${totalDelivered} поставлено - ${fulfillmentSupplies.reduce((sum, s) => sum + s.usedStock, 0)} использовано = ${expectedRemaining} шт`)
console.log(` Фактический остаток: ${totalInStock} шт`)
console.log(` ${expectedRemaining === totalInStock ? '✅' : '❌'} Соответствие: ${expectedRemaining === totalInStock ? 'КОРРЕКТНО' : 'ОШИБКА'}`)
console.log('')
console.log('=' .repeat(60))
console.log('✅ ПРОВЕРКА ЗАВЕРШЕНА')
} catch (error) {
console.error('❌ ОШИБКА при проверке:', error)
} finally {
await prisma.$disconnect()
}
}
checkUIFulfillmentStats()

View File

@ -0,0 +1,76 @@
const { PrismaClient } = require('@prisma/client')
const prisma = new PrismaClient()
async function cleanSupplyData() {
try {
console.log('🧹 ОЧИСТКА ДАННЫХ О ПОСТАВКАХ\n')
console.log('=' .repeat(80))
// 1. Удаляем все заказы поставок (каскадно удалятся и items)
console.log('\n📦 1. Удаление SUPPLY ORDERS...')
const deletedOrders = await prisma.supplyOrder.deleteMany({})
console.log(`✅ Удалено заказов поставок: ${deletedOrders.count}`)
// 2. Удаляем поставщиков расходников
console.log('\n🏭 2. Удаление SUPPLY SUPPLIERS...')
const deletedSuppliers = await prisma.supplySupplier.deleteMany({})
console.log(`✅ Удалено поставщиков: ${deletedSuppliers.count}`)
// 3. Удаляем расходники из таблицы Supply
console.log('\n🔧 3. Удаление SUPPLIES (расходники)...')
const deletedSupplies = await prisma.supply.deleteMany({})
console.log(`✅ Удалено расходников: ${deletedSupplies.count}`)
// 4. НЕ удаляем Products, так как это товары на складе поставщика
console.log('\n📦 4. PRODUCTS (товары на складах) - НЕ УДАЛЯЕМ')
console.log(' Товары на складах организаций оставлены без изменений')
// 5. Проверяем что осталось
console.log('\n\n📊 ПРОВЕРКА ПОСЛЕ ОЧИСТКИ:')
console.log('-' .repeat(80))
const remainingOrders = await prisma.supplyOrder.count()
const remainingSuppliers = await prisma.supplySupplier.count()
const remainingSupplies = await prisma.supply.count()
const remainingProducts = await prisma.product.count()
console.log(`📦 Supply Orders: ${remainingOrders}`)
console.log(`🏭 Supply Suppliers: ${remainingSuppliers}`)
console.log(`🔧 Supplies: ${remainingSupplies}`)
console.log(`📦 Products (не удалялись): ${remainingProducts}`)
console.log('\n✅ ОЧИСТКА ЗАВЕРШЕНА!')
} catch (error) {
console.error('❌ Ошибка при очистке:', error.message)
console.error(error)
} finally {
await prisma.$disconnect()
}
}
// Подтверждение перед очисткой
console.log('⚠️ ВНИМАНИЕ! Этот скрипт удалит:')
console.log('- Все заказы поставок (SupplyOrder)')
console.log('- Все записи поставщиков (SupplySupplier)')
console.log('- Все расходники (Supply)')
console.log('\nНЕ будут удалены:')
console.log('- Товары на складах (Product)')
console.log('- Организации и пользователи')
const readline = require('readline')
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
})
rl.question('\nВы уверены? (yes/да для подтверждения): ', (answer) => {
if (answer.toLowerCase() === 'yes' || answer.toLowerCase() === 'да') {
cleanSupplyData()
} else {
console.log('❌ Очистка отменена')
process.exit(0)
}
rl.close()
})

View File

@ -0,0 +1,163 @@
const { PrismaClient } = require('@prisma/client')
const prisma = new PrismaClient()
async function clearAllCabinetsData() {
try {
console.log('🧹 ОЧИСТКА ДАННЫХ ВСЕХ КАБИНЕТОВ...')
console.log('⚠️ Организации и пользователи НЕ УДАЛЯЮТСЯ')
console.log('🗑️ Удаляются только данные внутри кабинетов')
console.log('=' .repeat(50))
// 1. СКЛАДЫ И ПОСТАВКИ
console.log('\n1⃣ ОЧИСТКА СКЛАДОВ И ПОСТАВОК:')
console.log(' 🗑️ Удаляем SupplyOrderItem...')
const deletedOrderItems = await prisma.supplyOrderItem.deleteMany({})
console.log(` ✅ Удалено: ${deletedOrderItems.count}`)
console.log(' 🗑️ Удаляем SupplyOrder...')
const deletedOrders = await prisma.supplyOrder.deleteMany({})
console.log(` ✅ Удалено: ${deletedOrders.count}`)
console.log(' 🗑️ Удаляем Supply (расходники на складах)...')
const deletedSupplies = await prisma.supply.deleteMany({})
console.log(` ✅ Удалено: ${deletedSupplies.count}`)
// 2. ТОВАРЫ ПОСТАВЩИКОВ
console.log('\n2⃣ ОЧИСТКА ТОВАРОВ ПОСТАВЩИКОВ:')
console.log(' 🗑️ Удаляем Product (товары в каталогах поставщиков)...')
const deletedProducts = await prisma.product.deleteMany({})
console.log(` ✅ Удалено: ${deletedProducts.count}`)
// 3. УСЛУГИ ФУЛФИЛМЕНТА
console.log('\n3⃣ ОЧИСТКА УСЛУГ ФУЛФИЛМЕНТА:')
console.log(' 🗑️ Удаляем Service (услуги)...')
const deletedServices = await prisma.service.deleteMany({})
console.log(` ✅ Удалено: ${deletedServices.count}`)
console.log(' 🗑️ Удаляем Logistics (логистические маршруты)...')
const deletedLogistics = await prisma.logistics.deleteMany({})
console.log(` ✅ Удалено: ${deletedLogistics.count}`)
// 4. СОТРУДНИКИ
console.log('\n4⃣ ОЧИСТКА СОТРУДНИКОВ:')
console.log(' 🗑️ Удаляем Employee (сотрудники)...')
const deletedEmployees = await prisma.employee.deleteMany({})
console.log(` ✅ Удалено: ${deletedEmployees.count}`)
// 5. КОРЗИНЫ И ИЗБРАННОЕ
console.log('\n5⃣ ОЧИСТКА КОРЗИН И ИЗБРАННОГО:')
console.log(' 🗑️ Удаляем CartItem...')
const deletedCartItems = await prisma.cartItem.deleteMany({})
console.log(` ✅ Удалено: ${deletedCartItems.count}`)
console.log(' 🗑️ Удаляем Cart...')
const deletedCarts = await prisma.cart.deleteMany({})
console.log(` ✅ Удалено: ${deletedCarts.count}`)
console.log(' 🗑️ Удаляем Favorite...')
// Проверяем существование таблицы Favorite
let deletedFavorites = { count: 0 }
try {
deletedFavorites = await prisma.favorite.deleteMany({})
} catch (error) {
console.log(' ⚠️ Таблица Favorite не найдена, пропускаем')
}
console.log(` ✅ Удалено: ${deletedFavorites.count}`)
// 6. РЕКЛАМА И СТАТИСТИКА
console.log('\n6⃣ ОЧИСТКА РЕКЛАМЫ И СТАТИСТИКИ:')
console.log(' 🗑️ Удаляем ExternalAd (внешняя реклама)...')
const deletedAds = await prisma.externalAd.deleteMany({})
console.log(` ✅ Удалено: ${deletedAds.count}`)
// 7. СООБЩЕНИЯ
console.log('\n7⃣ ОЧИСТКА СООБЩЕНИЙ:')
console.log(' 🗑️ Удаляем Message (сообщения в мессенджере)...')
const deletedMessages = await prisma.message.deleteMany({})
console.log(` ✅ Удалено: ${deletedMessages.count}`)
// 8. КЕШИ И ВСПОМОГАТЕЛЬНЫЕ ДАННЫЕ
console.log('\n8⃣ ОЧИСТКА КЕШЕЙ:')
console.log(' 🗑️ Удаляем WBWarehouseCache...')
const deletedWarehouseCache = await prisma.wBWarehouseCache.deleteMany({})
console.log(` ✅ Удалено: ${deletedWarehouseCache.count}`)
console.log(' 🗑️ Удаляем SellerStatsCache...')
const deletedStatsCache = await prisma.sellerStatsCache.deleteMany({})
console.log(` ✅ Удалено: ${deletedStatsCache.count}`)
// 9. WILDBERRIES ПОСТАВКИ
console.log('\n9⃣ ОЧИСТКА ПОСТАВОК WILDBERRIES:')
console.log(' 🗑️ Удаляем WildberriesSupplyItem...')
let deletedWBItems = { count: 0 }
try {
deletedWBItems = await prisma.wildberriesSupplyItem.deleteMany({})
} catch (error) {
console.log(' ⚠️ Таблица WildberriesSupplyItem не найдена, пропускаем')
}
console.log(` ✅ Удалено: ${deletedWBItems.count}`)
console.log(' 🗑️ Удаляем WildberriesSupply...')
let deletedWBSupplies = { count: 0 }
try {
deletedWBSupplies = await prisma.wildberriesSupply.deleteMany({})
} catch (error) {
console.log(' ⚠️ Таблица WildberriesSupply не найдена, пропускаем')
}
console.log(` ✅ Удалено: ${deletedWBSupplies.count}`)
// ИТОГИ
console.log('\n' + '='.repeat(50))
console.log('✅ ОЧИСТКА ЗАВЕРШЕНА УСПЕШНО!')
console.log('')
console.log('🗑️ ЧТО БЫЛО УДАЛЕНО:')
console.log(` 📦 Заказы поставок: ${deletedOrders.count}`)
console.log(` 📋 Элементы заказов: ${deletedOrderItems.count}`)
console.log(` 🏪 Расходники на складах: ${deletedSupplies.count}`)
console.log(` 📦 Товары поставщиков: ${deletedProducts.count}`)
console.log(` 🛠️ Услуги фулфилмента: ${deletedServices.count}`)
console.log(` 🚚 Логистические маршруты: ${deletedLogistics.count}`)
console.log(` 👥 Сотрудники: ${deletedEmployees.count}`)
console.log(` 🛒 Корзины: ${deletedCarts.count}`)
console.log(` 📋 Элементы корзин: ${deletedCartItems.count}`)
console.log(` ❤️ Избранное: ${deletedFavorites.count}`)
console.log(` 📢 Реклама: ${deletedAds.count}`)
console.log(` 💬 Сообщения: ${deletedMessages.count}`)
console.log(` 📊 Кеш WB: ${deletedWarehouseCache.count}`)
console.log(` 📈 Кеш статистики: ${deletedStatsCache.count}`)
console.log(` 📦 Поставки WB: ${deletedWBSupplies.count}`)
console.log(` 📋 Элементы WB: ${deletedWBItems.count}`)
console.log('\n✅ ЧТО ОСТАЛОСЬ НЕТРОНУТЫМ:')
console.log(' 👤 Пользователи (User)')
console.log(' 🏢 Организации (Organization)')
console.log(' 🤝 Контрагенты (Counterparty)')
console.log(' 📋 Запросы на партнерство (CounterpartyRequest)')
console.log(' 📂 Категории товаров (Category)')
console.log(' 🎖️ Рефералы и сферы (ReferralTransaction)')
console.log(' 🔑 API ключи (MarketplaceApiKey)')
console.log('\n🎯 РЕЗУЛЬТАТ:')
console.log(' Все кабинеты очищены от данных')
console.log(' Система готова для чистого тестирования')
console.log(' Пользователи могут войти и начать работу заново')
} catch (error) {
console.error('❌ ОШИБКА при очистке:', error)
console.error(' Детали:', error.message)
} finally {
await prisma.$disconnect()
}
}
clearAllCabinetsData()

View File

@ -0,0 +1,70 @@
const { PrismaClient } = require('@prisma/client')
const prisma = new PrismaClient()
async function findUserByPhone() {
try {
console.log('🔍 ИЩЕМ ПОЛЬЗОВАТЕЛЯ ПО РАЗНЫМ ВАРИАНТАМ НОМЕРА...')
const phoneVariants = [
'+7 (999) 999-99-99',
'+79999999999',
'79999999999',
'9999999999',
'+7(999)999-99-99',
'+7 999 999 99 99'
]
for (const phone of phoneVariants) {
console.log(`\nПроверяем: "${phone}"`)
const user = await prisma.user.findFirst({
where: { phone: phone },
include: {
organization: true
}
})
if (user) {
console.log('✅ НАЙДЕН!')
console.log(' ID:', user.id)
console.log(' Телефон:', user.phone)
console.log(' Организация:', user.organization?.name || 'Нет')
console.log(' Тип:', user.organization?.type || 'Нет')
return user
}
}
console.log('\n❌ Не найден ни по одному варианту')
// Поищем похожие номера
console.log('\n🔍 ИЩЕМ ПОХОЖИЕ НОМЕРА (содержащие 9999):')
const similarUsers = await prisma.user.findMany({
where: {
phone: {
contains: '9999'
}
},
include: {
organization: true
},
take: 10
})
if (similarUsers.length > 0) {
console.log(`\nНайдено ${similarUsers.length} пользователей с похожими номерами:`)
similarUsers.forEach((user, index) => {
console.log(`${index + 1}. ${user.phone} - ${user.organization?.name || 'Без организации'} (${user.organization?.type || 'Неизвестный тип'})`)
})
} else {
console.log('\nПохожих номеров не найдено')
}
} catch (error) {
console.error('❌ Ошибка:', error.message)
} finally {
await prisma.$disconnect()
}
}
findUserByPhone()

View File

@ -0,0 +1,78 @@
const { PrismaClient } = require('@prisma/client')
const prisma = new PrismaClient()
async function fixSupplyOrderTypes() {
try {
console.log('🔧 ИСПРАВЛЯЕМ ТИПЫ ЗАКАЗОВ ПОСТАВОК...')
// Найдем все заказы поставок с проблемами
const problemOrders = await prisma.supplyOrder.findMany({
include: {
organization: {
select: {
id: true,
name: true,
type: true
}
}
}
})
console.log(`📋 Найдено заказов для анализа: ${problemOrders.length}`)
let fixedCount = 0
for (const order of problemOrders) {
const organizationType = order.organization?.type
const currentConsumableType = order.consumableType
// Определяем правильный тип на основе заказчика
let correctConsumableType
if (organizationType === 'SELLER') {
correctConsumableType = 'SELLER_CONSUMABLES'
} else if (organizationType === 'FULFILLMENT') {
correctConsumableType = 'FULFILLMENT_CONSUMABLES'
} else {
continue // Пропускаем другие типы
}
// Проверяем, нужно ли исправление
if (currentConsumableType !== correctConsumableType) {
console.log(`\n🔧 ИСПРАВЛЯЕМ ЗАКАЗ ${order.id}:`)
console.log(` Заказчик: ${order.organization?.name} (${organizationType})`)
console.log(` БЫЛО: ${currentConsumableType}`)
console.log(` СТАЛО: ${correctConsumableType}`)
// Обновляем заказ
await prisma.supplyOrder.update({
where: { id: order.id },
data: {
consumableType: correctConsumableType
}
})
fixedCount++
} else {
console.log(`✅ Заказ ${order.id} уже корректен (${organizationType}${currentConsumableType})`)
}
}
console.log(`\n📊 ИТОГИ:`)
console.log(` ✅ Исправлено заказов: ${fixedCount}`)
console.log(` 📋 Всего проверено: ${problemOrders.length}`)
if (fixedCount > 0) {
console.log(`\n⚠️ ВАЖНО: Нужно также пересоздать Supply записи с правильными типами!`)
console.log(` Проблемные Supply записи все еще имеют тип FULFILLMENT_CONSUMABLES`)
console.log(` но должны быть SELLER_CONSUMABLES для заказов от селлеров`)
}
} catch (error) {
console.error('❌ Ошибка при исправлении:', error.message)
} finally {
await prisma.$disconnect()
}
}
fixSupplyOrderTypes()

View File

@ -0,0 +1,113 @@
const { PrismaClient } = require('@prisma/client')
const prisma = new PrismaClient()
async function fixSupplyQuantity() {
try {
console.log('🔧 ИСПРАВЛЯЕМ НЕПРАВИЛЬНОЕ КОЛИЧЕСТВО В SUPPLY ЗАПИСИ')
console.log('=' .repeat(60))
// Находим проблемную Supply запись
const problemSupply = await prisma.supply.findFirst({
where: {
article: 'SF-C-285405-970',
type: 'FULFILLMENT_CONSUMABLES'
}
})
if (!problemSupply) {
console.log('❌ Supply запись не найдена')
return
}
console.log('📦 НАЙДЕНА ПРОБЛЕМНАЯ SUPPLY ЗАПИСЬ:')
console.log(` ID: ${problemSupply.id}`)
console.log(` Название: ${problemSupply.name}`)
console.log(` Артикул: ${problemSupply.article}`)
console.log(` НЕПРАВИЛЬНОЕ quantity: ${problemSupply.quantity}`)
console.log(` Текущий остаток: ${problemSupply.currentStock}`)
console.log('')
// Находим связанный заказ поставки чтобы узнать ПРАВИЛЬНОЕ количество
const relatedOrder = await prisma.supplyOrder.findFirst({
where: {
status: 'DELIVERED',
items: {
some: {
product: {
article: 'SF-C-285405-970'
}
}
}
},
include: {
items: {
include: {
product: true
}
}
}
})
if (!relatedOrder) {
console.log('❌ Связанный заказ поставки не найден')
return
}
const orderItem = relatedOrder.items.find(item => item.product.article === 'SF-C-285405-970')
if (!orderItem) {
console.log('❌ Товар в заказе не найден')
return
}
const correctQuantity = orderItem.quantity
console.log('📋 СВЯЗАННЫЙ ЗАКАЗ ПОСТАВКИ:')
console.log(` ID заказа: ${relatedOrder.id}`)
console.log(` ПРАВИЛЬНОЕ quantity: ${correctQuantity}`)
console.log('')
if (problemSupply.quantity === correctQuantity) {
console.log('✅ Количество уже корректно, исправление не требуется')
return
}
console.log('🔧 ИСПРАВЛЯЕМ SUPPLY ЗАПИСЬ:')
console.log(` БЫЛО: quantity = ${problemSupply.quantity}`)
console.log(` СТАЛО: quantity = ${correctQuantity}`)
console.log('')
// Исправляем quantity
const updatedSupply = await prisma.supply.update({
where: { id: problemSupply.id },
data: {
quantity: correctQuantity, // Правильное количество из заказа
}
})
console.log('✅ SUPPLY ЗАПИСЬ ИСПРАВЛЕНА!')
console.log(` ID: ${updatedSupply.id}`)
console.log(` Quantity: ${updatedSupply.quantity} (исправлено)`)
console.log(` CurrentStock: ${updatedSupply.currentStock} (остался без изменений)`)
console.log('')
console.log('🎯 ОЖИДАЕМЫЙ РЕЗУЛЬТАТ В UI:')
console.log(` Заказано: ${correctQuantity} шт`)
console.log(` Поставлено: ${correctQuantity} шт`)
console.log(` Остаток: ${updatedSupply.currentStock} шт`)
console.log(` Отправлено: 0 шт`)
console.log('')
console.log('=' .repeat(60))
console.log('✅ ИСПРАВЛЕНИЕ ЗАВЕРШЕНО')
} catch (error) {
console.error('❌ ОШИБКА при исправлении:', error)
console.error(' Детали:', error.message)
} finally {
await prisma.$disconnect()
}
}
fixSupplyQuantity()

View File

@ -0,0 +1,107 @@
const { PrismaClient } = require('@prisma/client')
const prisma = new PrismaClient()
async function fixSupplyTypes() {
try {
console.log('🔧 ИСПРАВЛЯЕМ ТИПЫ SUPPLY ЗАПИСЕЙ...')
// Найдем проблемную Supply запись "Тестовый Пакет"
const problemSupply = await prisma.supply.findFirst({
where: {
name: 'Тестовый Пакет',
article: 'ТП1755161624282',
type: 'FULFILLMENT_CONSUMABLES'
}
})
if (!problemSupply) {
console.log('❌ Supply запись "Тестовый Пакет" не найдена')
return
}
console.log('📦 НАЙДЕНА ПРОБЛЕМНАЯ SUPPLY ЗАПИСЬ:')
console.log(` ID: ${problemSupply.id}`)
console.log(` Название: ${problemSupply.name}`)
console.log(` Артикул: ${problemSupply.article}`)
console.log(` Текущий тип: ${problemSupply.type}`)
console.log(` Остаток: ${problemSupply.currentStock}`)
// Найдем заказы селлеров с этим товаром
const sellerOrders = await prisma.supplyOrder.findMany({
where: {
consumableType: 'SELLER_CONSUMABLES',
items: {
some: {
product: {
article: 'ТП1755161624282'
}
}
}
},
include: {
organization: {
select: {
id: true,
name: true,
type: true
}
}
}
})
if (sellerOrders.length > 0) {
// Это товар из заказов селлеров, нужно исправить
const firstSellerOrder = sellerOrders[0]
console.log(`\n🔧 ИСПРАВЛЯЕМ SUPPLY ЗАПИСЬ:`)
console.log(` Причина: Товар из заказов селлера "${firstSellerOrder.organization?.name}"`)
console.log(` БЫЛО: type = FULFILLMENT_CONSUMABLES, sellerOwnerId = null`)
console.log(` СТАЛО: type = SELLER_CONSUMABLES, sellerOwnerId = ${firstSellerOrder.organization?.id}`)
await prisma.supply.update({
where: { id: problemSupply.id },
data: {
type: 'SELLER_CONSUMABLES',
sellerOwnerId: firstSellerOrder.organization?.id
}
})
console.log('✅ Supply запись успешно исправлена!')
// Проверяем результат
const updatedSupply = await prisma.supply.findUnique({
where: { id: problemSupply.id },
include: {
sellerOwner: {
select: {
name: true,
type: true
}
}
}
})
console.log('\n📋 РЕЗУЛЬТАТ ИСПРАВЛЕНИЯ:')
console.log(` Тип: ${updatedSupply?.type}`)
console.log(` Владелец-селлер: ${updatedSupply?.sellerOwner?.name}`)
console.log(` Остаток: ${updatedSupply?.currentStock}`)
console.log('\n🎯 ОЖИДАЕМЫЙ РЕЗУЛЬТАТ В UI:')
console.log(' 📊 Карточка "Расходники селлеров": 10 штук')
console.log(' 📊 Карточка "Расходники фулфилмента": 0 штук')
console.log(' 📋 Столбец "Расходники селлеров" в таблице: 10 штук')
console.log(' 📋 Столбец "Расходники фулфилмента" в таблице: 0 штук')
} else {
console.log('❌ Не найдены связанные заказы селлеров')
}
} catch (error) {
console.error('❌ Ошибка при исправлении Supply:', error.message)
} finally {
await prisma.$disconnect()
}
}
fixSupplyTypes()

View File

@ -0,0 +1,284 @@
const { PrismaClient } = require('@prisma/client')
const prisma = new PrismaClient()
async function showAllSupplyData() {
try {
console.log('📊 ВСЕ ДАННЫЕ О ПОСТАВКАХ В СИСТЕМЕ\n')
console.log('=' .repeat(80))
// 1. SUPPLY ORDERS - Заказы поставок
console.log('\n📦 1. SUPPLY ORDERS (Заказы поставок):')
console.log('-' .repeat(80))
const supplyOrders = await prisma.supplyOrder.findMany({
include: {
organization: {
select: {
id: true,
name: true,
fullName: true,
type: true,
inn: true
}
},
partner: {
select: {
id: true,
name: true,
fullName: true,
type: true,
inn: true
}
},
fulfillmentCenter: {
select: {
id: true,
name: true,
fullName: true,
type: true
}
},
logisticsPartner: {
select: {
id: true,
name: true,
fullName: true,
type: true
}
},
items: {
include: {
product: {
select: {
id: true,
name: true,
article: true,
category: true
}
},
}
}
},
orderBy: {
createdAt: 'desc'
}
})
console.log(`Найдено заказов: ${supplyOrders.length}`)
supplyOrders.forEach((order, index) => {
console.log(`\n${index + 1}. Заказ #${order.id.slice(-8)}:`)
console.log(` 📅 Дата поставки: ${order.deliveryDate.toLocaleDateString('ru-RU')}`)
console.log(` 📊 Статус: ${order.status}`)
console.log(` 🏷️ Тип расходников: ${order.consumableType || 'НЕ УКАЗАН'}`)
console.log(` 💰 Сумма: ${order.totalAmount} руб.`)
console.log(` 📦 Позиций: ${order.totalItems}`)
console.log(` 👤 Создатель (${order.organization?.type}): ${order.organization?.name || order.organization?.fullName} (ИНН: ${order.organization?.inn})`)
console.log(` 🏭 Поставщик (${order.partner?.type}): ${order.partner?.name || order.partner?.fullName} (ИНН: ${order.partner?.inn})`)
if (order.fulfillmentCenter) {
console.log(` 🏢 Фулфилмент: ${order.fulfillmentCenter.name || order.fulfillmentCenter.fullName}`)
}
if (order.logisticsPartner) {
console.log(` 🚚 Логистика: ${order.logisticsPartner.name || order.logisticsPartner.fullName}`)
}
console.log(` 📋 Товары (${order.items.length}):`)
order.items.forEach((item, i) => {
console.log(` ${i + 1}. ${item.product.name} (Арт: ${item.product.article})`)
console.log(` Кол-во: ${item.quantity}, Цена: ${item.price} руб., Сумма: ${item.totalPrice} руб.`)
if (item.services?.length > 0) {
console.log(` 🔧 Услуги (ID): ${item.services.join(', ')}`)
}
if (item.fulfillmentConsumables?.length > 0) {
console.log(` 📦 Расходники ФФ (ID): ${item.fulfillmentConsumables.join(', ')}`)
}
if (item.sellerConsumables?.length > 0) {
console.log(` 🛍️ Расходники селлера (ID): ${item.sellerConsumables.join(', ')}`)
}
})
console.log(` 🕐 Создан: ${order.createdAt.toLocaleString('ru-RU')}`)
})
// 2. SUPPLY SUPPLIERS - Поставщики расходников
console.log('\n\n🏭 2. SUPPLY SUPPLIERS (Поставщики расходников):')
console.log('-' .repeat(80))
const supplySuppliers = await prisma.supplySupplier.findMany({
include: {
organization: {
select: {
id: true,
name: true,
type: true
}
}
}
})
console.log(`Найдено поставщиков: ${supplySuppliers.length}`)
supplySuppliers.forEach((supplier, index) => {
console.log(`\n${index + 1}. ${supplier.name}`)
console.log(` 📞 Контакт: ${supplier.contactName}`)
console.log(` ☎️ Телефон: ${supplier.phone}`)
console.log(` 📍 Адрес: ${supplier.address}`)
console.log(` 🏪 Рынок: ${supplier.market}`)
console.log(` 🏢 Организация: ${supplier.organization?.name} (${supplier.organization?.type})`)
})
// 3. PRODUCTS - Товары на складах
console.log('\n\n📦 3. PRODUCTS (Товары на складах):')
console.log('-' .repeat(80))
const products = await prisma.product.findMany({
include: {
category: true,
organization: {
select: {
id: true,
name: true,
type: true
}
}
},
where: {
organization: {
type: {
in: ['WHOLESALE', 'FULFILLMENT']
}
}
}
})
console.log(`Найдено товаров: ${products.length}`)
const productsByOrg = {}
products.forEach(product => {
const orgName = product.organization.name || 'Без названия'
const orgType = product.organization.type
const key = `${orgName} (${orgType})`
if (!productsByOrg[key]) {
productsByOrg[key] = []
}
productsByOrg[key].push(product)
})
Object.entries(productsByOrg).forEach(([orgKey, orgProducts]) => {
console.log(`\n${orgKey}: ${orgProducts.length} товаров`)
orgProducts.slice(0, 5).forEach((product, i) => {
console.log(` ${i + 1}. ${product.name} (Арт: ${product.article})`)
console.log(` Категория: ${product.category?.name || 'Без категории'}`)
console.log(` Цена: ${product.price} руб., Остаток: ${product.quantity}`)
})
if (orgProducts.length > 5) {
console.log(` ... и еще ${orgProducts.length - 5} товаров`)
}
})
// 4. SUPPLIES - Все расходники в системе
console.log('\n\n🔧 4. SUPPLIES (Все расходники в системе):')
console.log('-' .repeat(80))
const supplies = await prisma.supply.findMany({
include: {
organization: {
select: {
id: true,
name: true,
type: true
}
},
sellerOwner: {
select: {
id: true,
name: true,
type: true
}
}
}
})
console.log(`Найдено расходников: ${supplies.length}`)
// Группируем по типам
const suppliesByType = {}
supplies.forEach(supply => {
if (!suppliesByType[supply.type]) {
suppliesByType[supply.type] = []
}
suppliesByType[supply.type].push(supply)
})
Object.entries(suppliesByType).forEach(([type, typeSupplies]) => {
console.log(`\n${type}: ${typeSupplies.length} расходников`)
typeSupplies.forEach((supply, index) => {
console.log(` ${index + 1}. ${supply.name} (Арт: ${supply.article})`)
console.log(` 💰 Цена: ${supply.price} руб. за ${supply.unit}`)
console.log(` 📦 Остаток: ${supply.currentStock} из ${supply.minStock} мин.`)
console.log(` 🏢 Организация: ${supply.organization?.name} (${supply.organization?.type})`)
if (supply.sellerOwner) {
console.log(` 👤 Владелец-селлер: ${supply.sellerOwner.name}`)
}
})
})
// 5. СТАТИСТИКА
console.log('\n\n📊 5. СТАТИСТИКА:')
console.log('-' .repeat(80))
// Статистика по статусам
const statusStats = {}
supplyOrders.forEach(order => {
statusStats[order.status] = (statusStats[order.status] || 0) + 1
})
console.log('\nПо статусам:')
Object.entries(statusStats).forEach(([status, count]) => {
console.log(` ${status}: ${count} заказов`)
})
// Статистика по типам расходников
const typeStats = {}
supplyOrders.forEach(order => {
const type = order.consumableType || 'НЕ УКАЗАН'
typeStats[type] = (typeStats[type] || 0) + 1
})
console.log('\nПо типам расходников:')
Object.entries(typeStats).forEach(([type, count]) => {
console.log(` ${type}: ${count} заказов`)
})
// Статистика по организациям
const orgStats = {}
supplyOrders.forEach(order => {
const orgType = order.organization?.type || 'UNKNOWN'
orgStats[orgType] = (orgStats[orgType] || 0) + 1
})
console.log('\nПо типам организаций-создателей:')
Object.entries(orgStats).forEach(([type, count]) => {
console.log(` ${type}: ${count} заказов`)
})
// Общая сумма
const totalSum = supplyOrders.reduce((sum, order) => sum + (order.totalAmount || 0), 0)
console.log(`\n💰 Общая сумма всех заказов: ${totalSum.toLocaleString('ru-RU')} руб.`)
} catch (error) {
console.error('❌ Ошибка:', error.message)
console.error(error)
} finally {
await prisma.$disconnect()
}
}
// Запуск
showAllSupplyData()