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:
@ -171,6 +171,7 @@ export const GET_MY_FULFILLMENT_SUPPLIES = gql`
|
|||||||
currentStock
|
currentStock
|
||||||
usedStock
|
usedStock
|
||||||
imageUrl
|
imageUrl
|
||||||
|
productId
|
||||||
createdAt
|
createdAt
|
||||||
updatedAt
|
updatedAt
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,9 @@ import { WildberriesService } from '@/services/wildberries-service'
|
|||||||
import '@/lib/seed-init' // Автоматическая инициализация БД
|
import '@/lib/seed-init' // Автоматическая инициализация БД
|
||||||
// Импорт новых resolvers для системы поставок v2
|
// Импорт новых resolvers для системы поставок v2
|
||||||
import { fulfillmentConsumableV2Queries, fulfillmentConsumableV2Mutations } from './resolvers/fulfillment-consumables-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 { fulfillmentInventoryV2Queries } from './resolvers/fulfillment-inventory-v2'
|
||||||
|
import { logisticsConsumableV2Queries, logisticsConsumableV2Mutations } from './resolvers/logistics-consumables-v2'
|
||||||
import { CommercialDataAudit } from './security/commercial-data-audit'
|
import { CommercialDataAudit } from './security/commercial-data-audit'
|
||||||
import { createSecurityContext } from './security/index'
|
import { createSecurityContext } from './security/index'
|
||||||
|
|
||||||
@ -864,7 +866,8 @@ export const resolvers = {
|
|||||||
return []
|
return []
|
||||||
},
|
},
|
||||||
|
|
||||||
// Расходники фулфилмента из склада (новая архитектура - синхронизация со склада)
|
// ЗАКОММЕНТИРОВАНО: Старый resolver заменен на V2 из fulfillment-inventory-v2.ts
|
||||||
|
/*
|
||||||
myFulfillmentSupplies: async (_: unknown, __: unknown, context: Context) => {
|
myFulfillmentSupplies: async (_: unknown, __: unknown, context: Context) => {
|
||||||
console.warn('🔥🔥🔥 FULFILLMENT SUPPLIES RESOLVER CALLED (NEW ARCHITECTURE) 🔥🔥🔥')
|
console.warn('🔥🔥🔥 FULFILLMENT SUPPLIES RESOLVER CALLED (NEW ARCHITECTURE) 🔥🔥🔥')
|
||||||
|
|
||||||
@ -963,6 +966,7 @@ export const resolvers = {
|
|||||||
organizationId: item.fulfillmentCenterId,
|
organizationId: item.fulfillmentCenterId,
|
||||||
}))
|
}))
|
||||||
},
|
},
|
||||||
|
*/
|
||||||
|
|
||||||
// Заказы поставок расходников
|
// Заказы поставок расходников
|
||||||
supplyOrders: async (_: unknown, __: unknown, context: Context) => {
|
supplyOrders: async (_: unknown, __: unknown, context: Context) => {
|
||||||
@ -1252,17 +1256,18 @@ export const resolvers = {
|
|||||||
|
|
||||||
console.warn(`🏭 FULFILLMENT SUPPLY ORDERS: ${fulfillmentSupplyOrders.length}`)
|
console.warn(`🏭 FULFILLMENT SUPPLY ORDERS: ${fulfillmentSupplyOrders.length}`)
|
||||||
|
|
||||||
// Подсчитываем количество из таблицы Supply (актуальные остатки на складе фулфилмента)
|
// V2 СИСТЕМА: Подсчитываем количество из fulfillmentConsumableInventory
|
||||||
// ИСПРАВЛЕНО: считаем только расходники фулфилмента, исключаем расходники селлеров
|
const fulfillmentSuppliesFromWarehouse = await prisma.fulfillmentConsumableInventory.findMany({
|
||||||
const fulfillmentSuppliesFromWarehouse = await prisma.supply.findMany({
|
|
||||||
where: {
|
where: {
|
||||||
organizationId: organizationId, // Склад фулфилмента
|
fulfillmentCenterId: organizationId, // Склад фулфилмента
|
||||||
type: 'FULFILLMENT_CONSUMABLES', // ТОЛЬКО расходники фулфилмента
|
},
|
||||||
|
include: {
|
||||||
|
product: true,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
const fulfillmentSuppliesCount = fulfillmentSuppliesFromWarehouse.reduce(
|
const fulfillmentSuppliesCount = fulfillmentSuppliesFromWarehouse.reduce(
|
||||||
(sum, supply) => sum + (supply.currentStock || 0),
|
(sum, item) => sum + (item.currentStock || 0),
|
||||||
0,
|
0,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -1270,20 +1275,20 @@ export const resolvers = {
|
|||||||
`🔥 FULFILLMENT SUPPLIES DEBUG: organizationId=${organizationId}, ordersCount=${fulfillmentSupplyOrders.length}, warehouseCount=${fulfillmentSuppliesFromWarehouse.length}, totalStock=${fulfillmentSuppliesCount}`,
|
`🔥 FULFILLMENT SUPPLIES DEBUG: organizationId=${organizationId}, ordersCount=${fulfillmentSupplyOrders.length}, warehouseCount=${fulfillmentSuppliesFromWarehouse.length}, totalStock=${fulfillmentSuppliesCount}`,
|
||||||
)
|
)
|
||||||
console.warn(
|
console.warn(
|
||||||
'📦 FULFILLMENT SUPPLIES BREAKDOWN:',
|
'📦 FULFILLMENT SUPPLIES BREAKDOWN (V2):',
|
||||||
fulfillmentSuppliesFromWarehouse.map((supply) => ({
|
fulfillmentSuppliesFromWarehouse.map((item) => ({
|
||||||
name: supply.name,
|
name: item.product.name,
|
||||||
currentStock: supply.currentStock,
|
currentStock: item.currentStock,
|
||||||
supplier: supply.supplier,
|
totalReceived: item.totalReceived,
|
||||||
|
productId: item.product.id,
|
||||||
})),
|
})),
|
||||||
)
|
)
|
||||||
|
|
||||||
// Изменения расходников фулфилмента за сутки (ПРИБЫЛО)
|
// V2 СИСТЕМА: Изменения расходников фулфилмента за сутки (ПРИБЫЛО)
|
||||||
// Ищем заказы фулфилмента, доставленные на его склад за последние сутки
|
// Ищем поставки расходников V2, обновлённые за последние сутки
|
||||||
const fulfillmentSuppliesReceivedToday = await prisma.supplyOrder.findMany({
|
const fulfillmentSuppliesReceivedTodayV2 = await prisma.fulfillmentConsumableSupplyOrder.findMany({
|
||||||
where: {
|
where: {
|
||||||
organizationId: organizationId, // Заказчик = фулфилмент
|
fulfillmentCenterId: organizationId,
|
||||||
fulfillmentCenterId: organizationId, // ИСПРАВЛЕНО: доставлено НА склад фулфилмента
|
|
||||||
status: 'DELIVERED',
|
status: 'DELIVERED',
|
||||||
updatedAt: { gte: oneDayAgo },
|
updatedAt: { gte: oneDayAgo },
|
||||||
},
|
},
|
||||||
@ -1294,15 +1299,15 @@ export const resolvers = {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
const fulfillmentSuppliesChangeToday = fulfillmentSuppliesReceivedToday.reduce(
|
const fulfillmentSuppliesChangeToday = fulfillmentSuppliesReceivedTodayV2.reduce(
|
||||||
(sum, order) =>
|
(sum, supplyOrder) =>
|
||||||
sum +
|
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,
|
0,
|
||||||
)
|
)
|
||||||
|
|
||||||
console.warn(
|
console.warn(
|
||||||
`📊 FULFILLMENT SUPPLIES RECEIVED TODAY (ПРИБЫЛО): ${fulfillmentSuppliesReceivedToday.length} orders, ${fulfillmentSuppliesChangeToday} items`,
|
`📊 FULFILLMENT SUPPLIES RECEIVED TODAY V2 (ПРИБЫЛО): ${fulfillmentSuppliesReceivedTodayV2.length} orders, ${fulfillmentSuppliesChangeToday} items`,
|
||||||
)
|
)
|
||||||
|
|
||||||
// Расходники селлеров - получаем из таблицы Supply (актуальные остатки на складе фулфилмента)
|
// Расходники селлеров - получаем из таблицы Supply (актуальные остатки на складе фулфилмента)
|
||||||
@ -2844,8 +2849,11 @@ export const resolvers = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// Новая система поставок v2
|
// ВОССТАНОВЛЕННАЯ система поставок v2 из бэкапов
|
||||||
...fulfillmentConsumableV2Queries,
|
...fulfillmentConsumableV2QueriesRestored,
|
||||||
|
|
||||||
|
// V2 система поставок для логистики
|
||||||
|
...logisticsConsumableV2Queries,
|
||||||
|
|
||||||
// Новая система складских остатков V2 (заменяет старый myFulfillmentSupplies)
|
// Новая система складских остатков V2 (заменяет старый myFulfillmentSupplies)
|
||||||
...fulfillmentInventoryV2Queries,
|
...fulfillmentInventoryV2Queries,
|
||||||
@ -10491,8 +10499,11 @@ resolvers.Mutation = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// Добавляем v2 mutations через spread
|
// ВОССТАНОВЛЕННЫЕ v2 mutations из бэкапов
|
||||||
...fulfillmentConsumableV2Mutations,
|
...fulfillmentConsumableV2MutationsRestored,
|
||||||
|
|
||||||
|
// V2 mutations для логистики
|
||||||
|
...logisticsConsumableV2Mutations,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* // Резолвер для парсинга JSON рецептуры в SupplyOrderItem
|
/* // Резолвер для парсинга JSON рецептуры в SupplyOrderItem
|
||||||
|
@ -610,6 +610,7 @@ export const typeDefs = gql`
|
|||||||
|
|
||||||
type Supply {
|
type Supply {
|
||||||
id: ID!
|
id: ID!
|
||||||
|
productId: ID # ID продукта для фильтрации истории поставок
|
||||||
name: String!
|
name: String!
|
||||||
article: String! # ДОБАВЛЕНО: Артикул СФ для уникальности
|
article: String! # ДОБАВЛЕНО: Артикул СФ для уникальности
|
||||||
description: String
|
description: String
|
||||||
@ -1777,7 +1778,7 @@ export const typeDefs = gql`
|
|||||||
}
|
}
|
||||||
|
|
||||||
input ReceiveFulfillmentConsumableSupplyItemInput {
|
input ReceiveFulfillmentConsumableSupplyItemInput {
|
||||||
productId: ID!
|
id: ID!
|
||||||
receivedQuantity: Int!
|
receivedQuantity: Int!
|
||||||
defectQuantity: Int
|
defectQuantity: Int
|
||||||
}
|
}
|
||||||
@ -1820,10 +1821,6 @@ export const typeDefs = gql`
|
|||||||
supplierRejectConsumableSupply(id: ID!, reason: String): SupplierConsumableSupplyResponse!
|
supplierRejectConsumableSupply(id: ID!, reason: String): SupplierConsumableSupplyResponse!
|
||||||
supplierShipConsumableSupply(id: ID!): SupplierConsumableSupplyResponse!
|
supplierShipConsumableSupply(id: ID!): SupplierConsumableSupplyResponse!
|
||||||
|
|
||||||
# Мутации логистики для V2 расходников фулфилмента
|
|
||||||
logisticsConfirmConsumableSupply(id: ID!): SupplierConsumableSupplyResponse!
|
|
||||||
logisticsRejectConsumableSupply(id: ID!, reason: String): SupplierConsumableSupplyResponse!
|
|
||||||
|
|
||||||
# Мутация фулфилмента для приемки V2 расходников
|
# Мутация фулфилмента для приемки V2 расходников
|
||||||
fulfillmentReceiveConsumableSupply(
|
fulfillmentReceiveConsumableSupply(
|
||||||
id: ID!
|
id: ID!
|
||||||
@ -1967,4 +1964,25 @@ export const typeDefs = gql`
|
|||||||
# Отмена поставки селлером (только PENDING/APPROVED)
|
# Отмена поставки селлером (только PENDING/APPROVED)
|
||||||
cancelSellerSupply(id: ID!): SellerConsumableSupplyOrder!
|
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
|
||||||
|
}
|
||||||
`
|
`
|
||||||
|
Reference in New Issue
Block a user