feat(graphql): обновить систему на V2 архитектуру с улучшенной синхронизацией

- Переход с таблицы Supply на fulfillmentConsumableInventory для V2 системы
- Добавить productId в GraphQL схему Supply для корректной фильтрации
- Обновить резолверы статистики фулфилмента для использования V2 таблиц
- Исправить подсчёт ежедневных изменений с использованием V2 поставок
- Добавить синхронизацию данных между связанными компонентами

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Veronika Smirnova
2025-08-27 12:27:26 +03:00
parent b405daa1be
commit 0fe8a7072d
3 changed files with 60 additions and 30 deletions

View File

@ -171,6 +171,7 @@ export const GET_MY_FULFILLMENT_SUPPLIES = gql`
currentStock
usedStock
imageUrl
productId
createdAt
updatedAt
}

View File

@ -13,7 +13,9 @@ import { WildberriesService } from '@/services/wildberries-service'
import '@/lib/seed-init' // Автоматическая инициализация БД
// Импорт новых resolvers для системы поставок v2
import { fulfillmentConsumableV2Queries, fulfillmentConsumableV2Mutations } from './resolvers/fulfillment-consumables-v2'
import { fulfillmentConsumableV2Queries as fulfillmentConsumableV2QueriesRestored, fulfillmentConsumableV2Mutations as fulfillmentConsumableV2MutationsRestored } from './resolvers/fulfillment-consumables-v2-restored'
import { fulfillmentInventoryV2Queries } from './resolvers/fulfillment-inventory-v2'
import { logisticsConsumableV2Queries, logisticsConsumableV2Mutations } from './resolvers/logistics-consumables-v2'
import { CommercialDataAudit } from './security/commercial-data-audit'
import { createSecurityContext } from './security/index'
@ -864,7 +866,8 @@ export const resolvers = {
return []
},
// Расходники фулфилмента из склада (новая архитектура - синхронизация со склада)
// ЗАКОММЕНТИРОВАНО: Старый resolver заменен на V2 из fulfillment-inventory-v2.ts
/*
myFulfillmentSupplies: async (_: unknown, __: unknown, context: Context) => {
console.warn('🔥🔥🔥 FULFILLMENT SUPPLIES RESOLVER CALLED (NEW ARCHITECTURE) 🔥🔥🔥')
@ -963,6 +966,7 @@ export const resolvers = {
organizationId: item.fulfillmentCenterId,
}))
},
*/
// Заказы поставок расходников
supplyOrders: async (_: unknown, __: unknown, context: Context) => {
@ -1252,17 +1256,18 @@ export const resolvers = {
console.warn(`🏭 FULFILLMENT SUPPLY ORDERS: ${fulfillmentSupplyOrders.length}`)
// Подсчитываем количество из таблицы Supply (актуальные остатки на складе фулфилмента)
// ИСПРАВЛЕНО: считаем только расходники фулфилмента, исключаем расходники селлеров
const fulfillmentSuppliesFromWarehouse = await prisma.supply.findMany({
// V2 СИСТЕМА: Подсчитываем количество из fulfillmentConsumableInventory
const fulfillmentSuppliesFromWarehouse = await prisma.fulfillmentConsumableInventory.findMany({
where: {
organizationId: organizationId, // Склад фулфилмента
type: 'FULFILLMENT_CONSUMABLES', // ТОЛЬКО расходники фулфилмента
fulfillmentCenterId: organizationId, // Склад фулфилмента
},
include: {
product: true,
},
})
const fulfillmentSuppliesCount = fulfillmentSuppliesFromWarehouse.reduce(
(sum, supply) => sum + (supply.currentStock || 0),
(sum, item) => sum + (item.currentStock || 0),
0,
)
@ -1270,20 +1275,20 @@ export const resolvers = {
`🔥 FULFILLMENT SUPPLIES DEBUG: organizationId=${organizationId}, ordersCount=${fulfillmentSupplyOrders.length}, warehouseCount=${fulfillmentSuppliesFromWarehouse.length}, totalStock=${fulfillmentSuppliesCount}`,
)
console.warn(
'📦 FULFILLMENT SUPPLIES BREAKDOWN:',
fulfillmentSuppliesFromWarehouse.map((supply) => ({
name: supply.name,
currentStock: supply.currentStock,
supplier: supply.supplier,
'📦 FULFILLMENT SUPPLIES BREAKDOWN (V2):',
fulfillmentSuppliesFromWarehouse.map((item) => ({
name: item.product.name,
currentStock: item.currentStock,
totalReceived: item.totalReceived,
productId: item.product.id,
})),
)
// Изменения расходников фулфилмента за сутки (ПРИБЫЛО)
// Ищем заказы фулфилмента, доставленные на его склад за последние сутки
const fulfillmentSuppliesReceivedToday = await prisma.supplyOrder.findMany({
// V2 СИСТЕМА: Изменения расходников фулфилмента за сутки (ПРИБЫЛО)
// Ищем поставки расходников V2, обновлённые за последние сутки
const fulfillmentSuppliesReceivedTodayV2 = await prisma.fulfillmentConsumableSupplyOrder.findMany({
where: {
organizationId: organizationId, // Заказчик = фулфилмент
fulfillmentCenterId: organizationId, // ИСПРАВЛЕНО: доставлено НА склад фулфилмента
fulfillmentCenterId: organizationId,
status: 'DELIVERED',
updatedAt: { gte: oneDayAgo },
},
@ -1294,15 +1299,15 @@ export const resolvers = {
},
})
const fulfillmentSuppliesChangeToday = fulfillmentSuppliesReceivedToday.reduce(
(sum, order) =>
const fulfillmentSuppliesChangeToday = fulfillmentSuppliesReceivedTodayV2.reduce(
(sum, supplyOrder) =>
sum +
order.items.reduce((itemSum, item) => itemSum + (item.product.type === 'CONSUMABLE' ? item.quantity : 0), 0),
supplyOrder.items.reduce((itemSum, item) => itemSum + (item.receivedQuantity || 0), 0),
0,
)
console.warn(
`📊 FULFILLMENT SUPPLIES RECEIVED TODAY (ПРИБЫЛО): ${fulfillmentSuppliesReceivedToday.length} orders, ${fulfillmentSuppliesChangeToday} items`,
`📊 FULFILLMENT SUPPLIES RECEIVED TODAY V2 (ПРИБЫЛО): ${fulfillmentSuppliesReceivedTodayV2.length} orders, ${fulfillmentSuppliesChangeToday} items`,
)
// Расходники селлеров - получаем из таблицы Supply (актуальные остатки на складе фулфилмента)
@ -2844,8 +2849,11 @@ export const resolvers = {
}
},
// Новая система поставок v2
...fulfillmentConsumableV2Queries,
// ВОССТАНОВЛЕННАЯ система поставок v2 из бэкапов
...fulfillmentConsumableV2QueriesRestored,
// V2 система поставок для логистики
...logisticsConsumableV2Queries,
// Новая система складских остатков V2 (заменяет старый myFulfillmentSupplies)
...fulfillmentInventoryV2Queries,
@ -10491,8 +10499,11 @@ resolvers.Mutation = {
}
},
// Добавляем v2 mutations через spread
...fulfillmentConsumableV2Mutations,
// ВОССТАНОВЛЕННЫЕ v2 mutations из бэкапов
...fulfillmentConsumableV2MutationsRestored,
// V2 mutations для логистики
...logisticsConsumableV2Mutations,
}
/* // Резолвер для парсинга JSON рецептуры в SupplyOrderItem

View File

@ -610,6 +610,7 @@ export const typeDefs = gql`
type Supply {
id: ID!
productId: ID # ID продукта для фильтрации истории поставок
name: String!
article: String! # ДОБАВЛЕНО: Артикул СФ для уникальности
description: String
@ -1777,7 +1778,7 @@ export const typeDefs = gql`
}
input ReceiveFulfillmentConsumableSupplyItemInput {
productId: ID!
id: ID!
receivedQuantity: Int!
defectQuantity: Int
}
@ -1820,10 +1821,6 @@ export const typeDefs = gql`
supplierRejectConsumableSupply(id: ID!, reason: String): SupplierConsumableSupplyResponse!
supplierShipConsumableSupply(id: ID!): SupplierConsumableSupplyResponse!
# Мутации логистики для V2 расходников фулфилмента
logisticsConfirmConsumableSupply(id: ID!): SupplierConsumableSupplyResponse!
logisticsRejectConsumableSupply(id: ID!, reason: String): SupplierConsumableSupplyResponse!
# Мутация фулфилмента для приемки V2 расходников
fulfillmentReceiveConsumableSupply(
id: ID!
@ -1967,4 +1964,25 @@ export const typeDefs = gql`
# Отмена поставки селлером (только PENDING/APPROVED)
cancelSellerSupply(id: ID!): SellerConsumableSupplyOrder!
}
# === V2 ЛОГИСТИКА РАСХОДНИКОВ ФУЛФИЛМЕНТА ===
extend type Query {
# Получить V2 поставки для логистической компании
myLogisticsConsumableSupplies: [FulfillmentConsumableSupplyOrder!]!
}
extend type Mutation {
# Подтверждение поставки логистикой
logisticsConfirmConsumableSupply(id: ID!): LogisticsConsumableSupplyResponse!
# Отклонение поставки логистикой
logisticsRejectConsumableSupply(id: ID!, reason: String): LogisticsConsumableSupplyResponse!
}
# Ответ логистических операций V2
type LogisticsConsumableSupplyResponse {
success: Boolean!
message: String!
order: FulfillmentConsumableSupplyOrder
}
`