diff --git a/src/components/fulfillment-warehouse/fulfillment-warehouse-dashboard.tsx b/src/components/fulfillment-warehouse/fulfillment-warehouse-dashboard.tsx index 7d47071..4d357cb 100644 --- a/src/components/fulfillment-warehouse/fulfillment-warehouse-dashboard.tsx +++ b/src/components/fulfillment-warehouse/fulfillment-warehouse-dashboard.tsx @@ -227,10 +227,30 @@ export function FulfillmentWarehouseDashboard() { error: warehouseStatsError, refetch: refetchWarehouseStats, } = useQuery(GET_FULFILLMENT_WAREHOUSE_STATS, { - fetchPolicy: "cache-and-network", + fetchPolicy: "no-cache", // Принудительно обходим кеш pollInterval: 60000, // Обновляем каждую минуту }); + // Логируем статистику склада для отладки + console.log("📊 WAREHOUSE STATS DEBUG:", { + loading: warehouseStatsLoading, + error: warehouseStatsError?.message, + data: warehouseStatsData, + hasData: !!warehouseStatsData?.fulfillmentWarehouseStats, + }); + + // Детальное логирование данных статистики + if (warehouseStatsData?.fulfillmentWarehouseStats) { + console.log("📈 DETAILED WAREHOUSE STATS:", { + products: warehouseStatsData.fulfillmentWarehouseStats.products, + goods: warehouseStatsData.fulfillmentWarehouseStats.goods, + defects: warehouseStatsData.fulfillmentWarehouseStats.defects, + pvzReturns: warehouseStatsData.fulfillmentWarehouseStats.pvzReturns, + fulfillmentSupplies: warehouseStatsData.fulfillmentWarehouseStats.fulfillmentSupplies, + sellerSupplies: warehouseStatsData.fulfillmentWarehouseStats.sellerSupplies, + }); + } + // Получаем данные магазинов, заказов и товаров const allCounterparties = counterpartiesData?.myCounterparties || []; const sellerPartners = allCounterparties.filter( @@ -974,6 +994,7 @@ export function FulfillmentWarehouseDashboard() { icon: Icon, current, change, + percentChange, description, onClick, }: { @@ -981,10 +1002,14 @@ export function FulfillmentWarehouseDashboard() { icon: React.ComponentType<{ className?: string }>; current: number; change: number; + percentChange?: number; description: string; onClick?: () => void; }) => { - const percentChange = current > 0 ? (change / current) * 100 : 0; + // Используем percentChange из GraphQL, если доступно, иначе вычисляем локально + const displayPercentChange = percentChange !== undefined && percentChange !== null && !isNaN(percentChange) + ? percentChange + : (current > 0 ? (change / current) * 100 : 0); return (
= 0 ? "text-green-400" : "text-red-400" }`} > - {percentChange.toFixed(1)}% + {displayPercentChange.toFixed(1)}%
@@ -1199,6 +1224,7 @@ export function FulfillmentWarehouseDashboard() { icon={Box} current={warehouseStats.products.current} change={warehouseStats.products.change} + percentChange={warehouseStatsData?.fulfillmentWarehouseStats?.products?.percentChange} description="Готовые к отправке" /> router.push("/fulfillment-warehouse/supplies")} /> @@ -1235,6 +1265,7 @@ export function FulfillmentWarehouseDashboard() { icon={Users} current={warehouseStats.sellerSupplies.current} change={warehouseStats.sellerSupplies.change} + percentChange={warehouseStatsData?.fulfillmentWarehouseStats?.sellerSupplies?.percentChange} description="Материалы клиентов" /> diff --git a/src/graphql/resolvers.ts b/src/graphql/resolvers.ts index 63b105d..4a60252 100644 --- a/src/graphql/resolvers.ts +++ b/src/graphql/resolvers.ts @@ -1010,6 +1010,7 @@ export const resolvers = { // Статистика склада фулфилмента с изменениями за сутки fulfillmentWarehouseStats: async (_: unknown, __: unknown, context: Context) => { + console.log("🔥 FULFILLMENT WAREHOUSE STATS RESOLVER CALLED"); if (!context.user) { throw new GraphQLError("Требуется авторизация", { extensions: { code: "UNAUTHENTICATED" }, @@ -1035,35 +1036,66 @@ export const resolvers = { const oneDayAgo = new Date(); oneDayAgo.setDate(oneDayAgo.getDate() - 1); - // Продукты (товары селлеров на складе) - const products = await prisma.product.findMany({ + console.log(`🏢 Organization ID: ${organizationId}, Date 24h ago: ${oneDayAgo.toISOString()}`); + + // Сначала проверим ВСЕ заказы поставок + const allSupplyOrders = await prisma.supplyOrder.findMany({ + where: { status: "DELIVERED" }, + include: { + items: { + include: { product: true } + }, + organization: { select: { id: true, name: true, type: true } } + } + }); + console.log(`📦 ALL DELIVERED ORDERS: ${allSupplyOrders.length}`); + allSupplyOrders.forEach(order => { + console.log(` Order ${order.id}: org=${order.organizationId} (${order.organization?.name}), fulfillment=${order.fulfillmentCenterId}, items=${order.items.length}`); + }); + + // Продукты (товары от селлеров) - заказы К нам, но исключаем расходники фулфилмента + const allDeliveredOrders = await prisma.supplyOrder.findMany({ where: { - organization: { - type: "SELLER", - counterparties: { - some: { - OR: [ - { requesterId: organizationId }, - { receiverId: organizationId } - ] - } - } + fulfillmentCenterId: organizationId, // Доставлено к нам (фулфилменту) + status: "DELIVERED" + }, + include: { + items: { + include: { product: true } } } }); - const productsCount = products.reduce((sum, p) => sum + p.quantity, 0); - const productsChangeToday = 0; // TODO: реальные изменения - - // Товары (готовые товары для отправки) - const goods = await prisma.product.findMany({ + console.log(`🛒 ALL ORDERS TO FULFILLMENT: ${allDeliveredOrders.length}`); + + const productsCount = sellerDeliveredOrders.reduce((sum, order) => + sum + order.items.reduce((itemSum, item) => + itemSum + (item.product.type === "PRODUCT" ? item.quantity : 0), 0 + ), 0 + ); + // Изменения товаров за сутки (от селлеров) + const recentSellerDeliveredOrders = await prisma.supplyOrder.findMany({ where: { - // Готовые товары - пока нет реальных данных - organizationId: organizationId, - type: "READY" + fulfillmentCenterId: organizationId, // К нам + organizationId: { not: organizationId }, // От селлеров + status: "DELIVERED", + updatedAt: { gte: oneDayAgo } + }, + include: { + items: { + include: { product: true } + } } }); - const goodsCount = goods.reduce((sum, p) => sum + p.quantity, 0); - const goodsChangeToday = 0; + + const productsChangeToday = recentSellerDeliveredOrders.reduce((sum, order) => + sum + order.items.reduce((itemSum, item) => + itemSum + (item.product.type === "PRODUCT" ? item.quantity : 0), 0 + ), 0 + ); + + // Товары (готовые товары = все продукты, не расходники) + const goodsCount = productsCount; // Готовые товары = все продукты + const goodsChangeToday = productsChangeToday; // Изменения товаров = изменения продуктов // Брак const defectsCount = 0; // TODO: реальные данные о браке @@ -1073,77 +1105,75 @@ export const resolvers = { const pvzReturnsCount = 0; // TODO: реальные данные о возвратах const pvzReturnsChangeToday = 0; - // Расходники фулфилмента + // Расходники фулфилмента - заказы ОТ фулфилмента К поставщикам const fulfillmentSupplyOrders = await prisma.supplyOrder.findMany({ where: { - organizationId: organizationId, - fulfillmentCenterId: organizationId, + organizationId: organizationId, // Заказчик = фулфилмент + fulfillmentCenterId: null, // Не является доставкой к фулфилменту status: "DELIVERED" }, - include: { items: true } + include: { + items: { + include: { product: true } + } + } }); + console.log(`🏭 FULFILLMENT SUPPLY ORDERS: ${fulfillmentSupplyOrders.length}`); const fulfillmentSuppliesCount = fulfillmentSupplyOrders.reduce( - (sum, order) => sum + order.items.reduce((itemSum, item) => itemSum + item.quantity, 0), - 0 + (sum, order) => sum + order.items.reduce((itemSum, item) => + itemSum + (item.product.type === "CONSUMABLE" ? item.quantity : 0), 0 + ), 0 ); + console.log(`🔥 FULFILLMENT SUPPLIES DEBUG: organizationId=${organizationId}, totalOrders=${fulfillmentSupplyOrders.length}, totalCount=${fulfillmentSuppliesCount}`); + // Изменения расходников фулфилмента за сутки const fulfillmentSuppliesReceivedToday = await prisma.supplyOrder.findMany({ where: { - organizationId: organizationId, - fulfillmentCenterId: organizationId, + organizationId: organizationId, // Заказчик = фулфилмент + fulfillmentCenterId: null, // Не доставка к фулфилменту status: "DELIVERED", updatedAt: { gte: oneDayAgo } }, - include: { items: true } - }); - const fulfillmentSuppliesChangeToday = fulfillmentSuppliesReceivedToday.reduce( - (sum, order) => sum + order.items.reduce((itemSum, item) => itemSum + item.quantity, 0), - 0 - ); - - // Расходники селлеров - const sellerSupplies = await prisma.supply.findMany({ - where: { - organizationId: { - not: organizationId - }, - organization: { - counterparties: { - some: { - OR: [ - { requesterId: organizationId }, - { receiverId: organizationId } - ] - } - } + include: { + items: { + include: { product: true } } } }); - const sellerSuppliesCount = sellerSupplies.reduce((sum, s) => sum + s.currentStock, 0); - - // Изменения расходников селлеров за сутки - const sellerSuppliesReceivedToday = await prisma.supplyOrder.findMany({ - where: { - fulfillmentCenterId: organizationId, - organizationId: { not: organizationId }, - status: "DELIVERED", - updatedAt: { gte: oneDayAgo } - }, - include: { items: true } - }); - const sellerSuppliesChangeToday = sellerSuppliesReceivedToday.reduce( - (sum, order) => sum + order.items.reduce((itemSum, item) => itemSum + item.quantity, 0), - 0 + const fulfillmentSuppliesChangeToday = fulfillmentSuppliesReceivedToday.reduce( + (sum, order) => sum + order.items.reduce((itemSum, item) => + itemSum + (item.product.type === "CONSUMABLE" ? item.quantity : 0), 0 + ), 0 ); + console.log(`📊 FULFILLMENT SUPPLIES RECEIVED TODAY: ${fulfillmentSuppliesReceivedToday.length} orders, ${fulfillmentSuppliesChangeToday} items`); + + // Расходники селлеров - получаем из заказов от селлеров (расходники = CONSUMABLE) + const sellerSuppliesCount = sellerDeliveredOrders.reduce((sum, order) => + sum + order.items.reduce((itemSum, item) => + itemSum + (item.product.type === "CONSUMABLE" ? item.quantity : 0), 0 + ), 0 + ); + + console.log(`💼 SELLER SUPPLIES DEBUG: totalCount=${sellerSuppliesCount} (from delivered orders)`); + + // Изменения расходников селлеров за сутки - используем уже полученные данные + const sellerSuppliesChangeToday = recentSellerDeliveredOrders.reduce((sum, order) => + sum + order.items.reduce((itemSum, item) => + itemSum + (item.product.type === "CONSUMABLE" ? item.quantity : 0), 0 + ), 0 + ); + + console.log(`📊 SELLER SUPPLIES RECEIVED TODAY: ${recentSellerDeliveredOrders.length} orders, ${sellerSuppliesChangeToday} items`); + // Вычисляем процентные изменения const calculatePercentChange = (current: number, change: number): number => { if (current === 0) return change > 0 ? 100 : 0; return (change / current) * 100; }; - return { + const result = { products: { current: productsCount, change: productsChangeToday, @@ -1175,6 +1205,10 @@ export const resolvers = { percentChange: calculatePercentChange(sellerSuppliesCount, sellerSuppliesChangeToday) } }; + + console.log(`🏁 FINAL WAREHOUSE STATS RESULT:`, JSON.stringify(result, null, 2)); + + return result; }, // Логистика организации