EverydayTech Platform - Developer Reference
Complete Source Code Documentation - All Applications
Loading...
Searching...
No Matches
fieldpine.ts
Go to the documentation of this file.
1// Updated Fieldpine integration - now uses secure server-side API
2import { FieldpineConfig } from './config';
3import { apiClient, type ApiResponse } from './client/apiClient';
4
5export class FieldpineIntegration {
6 private config: FieldpineConfig;
7
8 constructor(config: FieldpineConfig) {
9 this.config = config;
10 }
11
12 // Legacy methods for backward compatibility
13 setAuth(apiKey: string, retailerId?: string) {
14 console.warn('setAuth is deprecated - authentication is now handled server-side');
15 }
16
17 getAuth() {
18 console.warn('getAuth is deprecated - authentication is now handled server-side');
19 return { apiKey: null, retailerId: null };
20 }
21
22 buildUrl(endpoint: string, params?: Record<string, any>) {
23 console.warn('buildUrl is deprecated - API calls are now handled server-side');
24 return '';
25 }
26
27 // Updated API methods using secure server endpoints
28 async getProducts(params?: { limit?: number; search?: string; plu?: string; barcode?: string }): Promise<any> {
29 // Note: 'search' parameter gets mapped to 'EnglishQuery' for OpenAPI
30 const result = await apiClient.getProducts(params || {});
31 if (!result.success) {
32 throw new Error(result.error || 'Failed to fetch products');
33 }
34 return result.data;
35 }
36
37 async getProductById(id: string): Promise<any> {
38 const result = await apiClient.getProductById(id);
39 if (!result.success) {
40 throw new Error(result.error || 'Failed to fetch product');
41 }
42 return result.data;
43 }
44
45 async getProductByPlu(plu: string): Promise<any> {
46 return this.getProducts({ plu });
47 }
48
49 async getProductByBarcode(barcode: string): Promise<any> {
50 return this.getProducts({ barcode });
51 }
52
53 async getLocations(params?: { source?: "openapi" | "elink"; want?: string }): Promise<any> {
54 const result = await apiClient.getLocations(params || {});
55 if (!result.success) {
56 throw new Error(result.error || 'Failed to fetch locations');
57 }
58 return result.data;
59 }
60
61 async getCustomers(params?: { search?: string; limit?: number }): Promise<any> {
62 const result = await apiClient.getCustomers(params || {});
63 if (!result.success) {
64 throw new Error(result.error || 'Failed to fetch customers');
65 }
66 return result.data;
67 }
68
69 async createSale(payload: any): Promise<any> {
70 const result = await apiClient.createSale(payload);
71 if (!result.success) {
72 throw new Error(result.error || 'Failed to create sale');
73 }
74 return result.data;
75 }
76
77 // Legacy placeholder methods for backward compatibility
78 async getPublicMessages(params?: { limit?: number }): Promise<any> {
79 return { messages: [], params };
80 }
81
82 async getCurrentBill(): Promise<any> {
83 return { currentBill: null };
84 }
85
86 async getCustomerById(id: string): Promise<any> {
87 return { id, customer: null };
88 }
89
90 async updateCustomer(id: string, updates: Record<string, any>): Promise<any> {
91 return { id, updated: false, updates };
92 }
93
94 async getSuppliers(params?: { limit?: number; search?: string }): Promise<any> {
95 const result = await apiClient.getSuppliers(params || {});
96 if (!result.success) {
97 throw new Error(result.error || 'Failed to fetch suppliers');
98 }
99 return result.data;
100 }
101
102 async getSupplierById(id: string): Promise<any> {
103 return { id, supplier: null };
104 }
105
106 async getStockOnHand(params?: { locationId?: string; productId?: string; limit?: number }): Promise<any> {
107 return { stock: [], params };
108 }
109
110 async createStockAdjustment(adjustment: { productId: string; locationId: string; qty: number; reason?: string }): Promise<any> {
111 return { accepted: false, adjustment };
112 }
113
114 async getStaff(params?: { limit?: number; search?: string }): Promise<any> {
115 return { staff: [], params };
116 }
117
118 async getStaffById(id: string): Promise<any> {
119 return { id, staff: null };
120 }
121
122 async getReportsSummary(params?: { dateFrom?: string; dateTo?: string; type?: string }): Promise<any> {
123 return { reports: [], params };
124 }
125
126 async finalizeSale(saleId: string, tender: Array<{ type: string; amount: number }>): Promise<any> {
127 return { saleId, finalized: false, tender };
128 }
129
130 async voidSale(saleId: string, reason?: string): Promise<any> {
131 return { saleId, voided: false, reason };
132 }
133}
134
135// Global instance - now SSR safe
136function getFieldpineConfig() {
137 if (typeof window === 'undefined') {
138 // Server-side: try to load config file or use environment variables
139 try {
140 return require('./config').defaultConfig;
141 } catch {
142 // Config file doesn't exist, use environment variables
143 return {
144 baseUrl: process.env.NEXT_PUBLIC_FIELDPINE_BASE_URL || 'https://api.fieldpine.com',
145 retailerId: process.env.NEXT_PUBLIC_FIELDPINE_RETAILER_ID || 'demo',
146 apiKey: null
147 };
148 }
149 }
150
151 // Client-side: try localStorage first, then config file, then env vars
152 if (typeof window !== "undefined") {
153 try {
154 const stored = localStorage.getItem("fieldpine_config");
155 if (stored) {
156 return JSON.parse(stored);
157 }
158 } catch (error) {
159 console.warn('Error loading fieldpine config from localStorage:', error);
160 }
161 }
162
163 try {
164 return require('./config').defaultConfig;
165 } catch {
166 // Config file doesn't exist, use environment variables with CWA defaults
167 return {
168 baseUrl: process.env.NEXT_PUBLIC_FIELDPINE_BASE_URL || 'https://a1.fieldpine.com',
169 retailerId: process.env.NEXT_PUBLIC_FIELDPINE_RETAILER_ID || 'CWA',
170 apiKey: process.env.FIELDPINE_API_KEY || process.env.FIELDPINE_AUTH_HEADER || 'dWx1cnU6YWxpY2U=',
171 minpos: parseInt(process.env.FIELDPINE_MIN_POS || '2370'),
172 mingds: parseInt(process.env.FIELDPINE_MIN_GDS || '264'),
173 uiname: process.env.FIELDPINE_UI_NAME || 'CWA Standard',
174 password: process.env.NEXT_PUBLIC_DEMO_PASSWORD || 'emu'
175 };
176 }
177}
178
179let _fieldpineInstance: FieldpineIntegration | null = null;
180
181export const fieldpine = new Proxy({} as FieldpineIntegration, {
182 get(target, prop) {
183 if (!_fieldpineInstance) {
184 const config = getFieldpineConfig();
185 _fieldpineInstance = new FieldpineIntegration(config);
186 }
187 return _fieldpineInstance[prop as keyof FieldpineIntegration];
188 }
189});