EverydayTech Platform - Developer Reference
Complete Source Code Documentation - All Applications
Loading...
Searching...
No Matches
route.ts
Go to the documentation of this file.
1import { NextRequest, NextResponse } from 'next/server';
2import { FieldpineServerApi } from '@/lib/server/fieldpineApi';
3import { getRequestContext, validateApiAccess, getStoreApiUrl } from '@/lib/server/sessionUtils';
4
5/**
6 * Sales Detail Report (Line-by-Line)
7 * ELINK: retailmax.elink.saleflat.list
8 * Returns detailed line items for all sales transactions
9 */
10export async function GET(request: NextRequest) {
11 try {
12 // Get session context
13 const context = await getRequestContext(request);
14 if (!context || !context.isAuthenticated) {
15 return NextResponse.json(
16 { error: 'Authentication required' },
17 { status: 401 }
18 );
19 }
20
21 // Validate ELINK access
22 if (!validateApiAccess(context, 'elink')) {
23 return NextResponse.json(
24 { error: 'ELINK access not permitted for this store type' },
25 { status: 403 }
26 );
27 }
28
29 const { searchParams } = new URL(request.url);
30
31 // Date filters
32 const startDate = searchParams.get('startDate'); // YYYY-MM-DD
33 const endDate = searchParams.get('endDate'); // YYYY-MM-DD
34 const limit = searchParams.get('limit') || '200';
35
36 // Location filter
37 const locationId = searchParams.get('locationId');
38
39 // Department filter
40 const departmentId = searchParams.get('departmentId');
41
42 // Create store-specific API instance
43 const storeApiUrl = getStoreApiUrl(context, 'elink');
44 const api = new FieldpineServerApi(storeApiUrl, context.session.apiKey);
45
46 console.log('[Sales Detail] Calling ELINK: retailmax.elink.saleflat.list');
47
48 // Build BUCK parameters
49 const buckParams: Record<string, string | string[]> = {
50 "3": "retailmax.elink.saleflat.list",
51 "8": limit, // Limit records
52 "103": "1", // Include product details
53 "104": "1" // Include customer details
54 };
55
56 // Add date and other filters
57 const filters: string[] = [];
58 if (startDate) {
59 filters.push(`f102,4,${startDate}`); // Start date (f102 = sale date)
60 }
61 if (endDate) {
62 filters.push(`f102,1,${endDate}`); // End date
63 }
64 if (locationId) {
65 filters.push(`f131,2,${locationId}`); // f131 = location
66 }
67 if (departmentId) {
68 filters.push(`f133,2,${departmentId}`); // f133 = department
69 }
70 if (filters.length > 0) {
71 buckParams["9"] = filters;
72 }
73
74 const result = await api.buckApiCall(buckParams, context.session.apiKey);
75
76 // Process BUCK response
77 if (result && result.DATS && Array.isArray(result.DATS)) {
78 const sales = result.DATS.map((item: any) => ({
79 saleId: item.f100,
80 saleDate: item.f102,
81 productId: item.f200,
82 productName: item.f201,
83 barcode: item.f202,
84 quantity: item.f210,
85 unitPrice: item.f211,
86 lineTotal: item.f212,
87 locationId: item.f131,
88 locationName: item.f132,
89 departmentId: item.f133,
90 departmentName: item.f134,
91 tellerId: item.f140,
92 tellerName: item.f141,
93 customerId: item.f300,
94 customerName: item.f301,
95 paymentType: item.f250,
96 tax: item.f213,
97 discount: item.f214
98 }));
99
100 return NextResponse.json({
101 success: true,
102 data: sales,
103 count: sales.length,
104 source: 'elink'
105 });
106 }
107
108 return NextResponse.json({
109 success: true,
110 data: [],
111 count: 0,
112 source: 'elink'
113 });
114
115 } catch (error) {
116 console.error('[Sales Detail] Error:', error);
117 return NextResponse.json(
118 { error: 'Failed to fetch sales detail' },
119 { status: 500 }
120 );
121 }
122}