1import { NextRequest, NextResponse } from 'next/server';
2import { fieldpineServerApi } from '@/lib/server/fieldpineApi';
3import { getStoredAuth } from '@/lib/server/auth';
6 * Pareto Analysis (80/20 Rule)
7 * BUCK: retailmax.elink.product.paretolist
8 * Returns top performing products by various metrics
10export async function GET(request: NextRequest) {
12 const authData = await getStoredAuth();
13 if (!authData || !authData.authenticated) {
14 return NextResponse.json(
15 { error: 'Authentication required' },
20 const { searchParams } = new URL(request.url);
23 const startDate = searchParams.get('startDate');
24 const endDate = searchParams.get('endDate');
25 const limit = searchParams.get('limit') || '50';
27 // Analysis type: basketrate, grossmargin, returns, volume, revenue
28 const type = searchParams.get('type') || 'revenue';
30 // Build BUCK parameters
31 const params: string[] = [
32 '3=retailmax.elink.product.paretolist',
38 params.push(`9=f102,4,${startDate}`);
41 params.push(`9=f102,1,${endDate}`);
47 params.push('100=1'); // Sort by basket rate
50 params.push('100=2'); // Sort by gross margin
53 params.push('100=3'); // Sort by return rate
56 params.push('100=4'); // Sort by units sold
60 params.push('100=5'); // Sort by revenue (default)
64 const query = params.join('&');
65 const url = `/GNAP/j/buck?${query}`;
67 console.log('[Pareto Analysis] BUCK query:', url);
69 const result = await fieldpineServerApi.apiCall(url, {
70 cookie: authData.apiKey,
74 // Process BUCK response
75 if (result && result.DATS && Array.isArray(result.DATS)) {
76 const products = result.DATS.map((item: any, index: number) => ({
79 productName: item.f201,
84 grossProfit: item.f213,
85 grossMargin: item.f214,
86 basketRate: item.f220, // % of transactions containing this item
87 returnRate: item.f221,
88 averagePrice: item.f222,
89 supplierId: item.f230,
90 supplierName: item.f231,
91 departmentId: item.f240,
92 departmentName: item.f241,
93 percentOfTotal: item.f250 // Cumulative % contribution
96 // Calculate 80/20 breakpoint
97 const breakpoint = products.findIndex((p: any) => p.percentOfTotal >= 80);
99 return NextResponse.json({
102 count: products.length,
105 top20PercentCount: Math.ceil(products.length * 0.2),
106 eightyPercentBreakpoint: breakpoint > 0 ? breakpoint : products.length,
107 top20PercentRevenue: products.slice(0, Math.ceil(products.length * 0.2))
108 .reduce((sum: number, p: any) => sum + (p.revenue || 0), 0)
114 return NextResponse.json({
123 console.error('[Pareto Analysis] Error:', error);
124 return NextResponse.json(
125 { error: 'Failed to fetch pareto analysis' },