@markwharton/eh-payroll 2.4.0 → 2.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -71,38 +71,11 @@ if (groupResult.ok) console.log(groupResult.data); // EHEmployeeGroup[]
71
71
  const hoursResult = await client.getStandardHours(employeeId);
72
72
  if (hoursResult.ok) console.log(hoursResult.data); // EHStandardHours
73
73
 
74
- // Discover available report columns
75
- const fieldsResult = await client.getReportFields();
76
- if (fieldsResult.ok) console.log(fieldsResult.data); // EHReportField[]
77
-
78
- // Run Employee Details Report with selected columns
79
- const reportResult = await client.getEmployeeDetailsReport({
80
- selectedColumns: ['FirstName', 'Surname', 'ExternalId']
81
- });
82
- if (reportResult.ok) console.log(reportResult.data); // Record<string, unknown>[]
83
74
  ```
84
75
 
85
76
  ## Result Pattern
86
77
 
87
- All methods return `Result<T>` objects rather than throwing exceptions. Always check `ok` before accessing `data`:
88
-
89
- ```typescript
90
- interface Result<T> {
91
- ok: boolean;
92
- data?: T; // present when ok is true
93
- error?: string; // present when ok is false
94
- status?: number; // HTTP status code on error
95
- }
96
- ```
97
-
98
- ```typescript
99
- const result = await client.getEmployees();
100
- if (!result.ok) {
101
- console.error(result.error, result.status);
102
- return;
103
- }
104
- const employees = result.data;
105
- ```
78
+ All methods return `Result<T>` see [api-core Result Pattern](../../README.md#result-pattern). Always check `ok` before accessing `data`.
106
79
 
107
80
  ## API Reference
108
81
 
@@ -117,17 +90,20 @@ const employees = result.data;
117
90
  | `getRosterShifts(from, to, options?)` | `string, string, EHRosterShiftOptions?` | `Result<EHRosterShift[]>` |
118
91
  | `getKiosks()` | — | `Result<EHKiosk[]>` |
119
92
  | `getKioskStaff(kioskId, options?)` | `number, EHKioskStaffOptions?` | `Result<EHKioskEmployee[]>` |
120
- | `getReportFields()` | — | `Result<EHReportField[]>` |
121
93
  | `getLeaveRequests(options?)` | `EHLeaveRequestOptions?` | `Result<EHLeaveRequest[]>` |
122
- | `getEmployeeDetailsReport(options?)` | `EHEmployeeDetailsReportOptions?` | `Result<Record<string, unknown>[]>` |
94
+ | `getEmployeeLeaveRequests(employeeId, options?)` | `number, EHEmployeeLeaveRequestOptions?` | `Result<EHLeaveRequest[]>` |
95
+ | `clearCache()` | — | `void` |
96
+ | `invalidateEmployeeCache()` | — | `void` |
97
+ | `invalidateLeaveRequestCache()` | — | `void` |
98
+ | `invalidateRosterShiftCache()` | — | `void` |
99
+ | `invalidateLocationCache()` | — | `void` |
100
+ | `invalidateKioskCache()` | — | `void` |
123
101
 
124
102
  ### `getLeaveRequests()`
125
103
 
126
- Returns leave requests with all filters applied server-side. The business-level endpoint (`/api/v2/business/{businessId}/leaverequest`) returns a flat array — no pagination is available.
127
-
128
- **Leave requests are time-series data** — unlike employees and locations which remain relatively stable, leave requests grow continuously as new requests accumulate. Always use `fromDate`/`toDate` filters to bound the result set. Without date filters, the API returns the entire leave request history.
104
+ Returns leave requests with all filters applied server-side. The business-level endpoint returns a flat array — no pagination.
129
105
 
130
- > **Note:** The Payroll API also provides a per-employee endpoint (`/api/v2/business/{businessId}/employee/{employeeId}/leaverequest`) with OData support (`$filter`, `$orderby`, `$top`, `$skip`). This client currently uses only the business-level endpoint.
106
+ **Leave requests are time-series data** unlike employees and locations which remain relatively stable, leave requests grow continuously. Always use `fromDate`/`toDate` filters to bound the result set.
131
107
 
132
108
  **`EHLeaveRequestOptions`:**
133
109
 
@@ -140,9 +116,17 @@ Returns leave requests with all filters applied server-side. The business-level
140
116
  | `leaveCategoryId` | `number` | Filter by leave category ID |
141
117
  | `locationId` | `number` | Filter by location ID |
142
118
 
143
- ### `getEmployeeDetailsReport()`
119
+ ### `getEmployeeLeaveRequests()`
120
+
121
+ Returns leave requests for a specific employee using the per-employee endpoint with OData pagination.
122
+
123
+ **`EHEmployeeLeaveRequestOptions`:**
144
124
 
145
- Returns all employees with the requested columns in a single API call. The response is dynamic — field keys depend on `selectedColumns`. Results are cached with `employeeDetailsReportTtl` (default: 2 min).
125
+ | Option | Type | Description |
126
+ |--------|------|-------------|
127
+ | `status` | `EHLeaveRequestStatus` | `'Approved'`, `'Pending'`, `'Rejected'`, or `'Cancelled'` |
128
+ | `fromDate` | `string` | Start date filter (ISO 8601) |
129
+ | `toDate` | `string` | End date filter (ISO 8601) |
146
130
 
147
131
  ### `getRosterShifts()`
148
132
 
@@ -172,7 +156,7 @@ const client = new EHClient({
172
156
  });
173
157
  ```
174
158
 
175
- `EHConfig` extends `ClientConfig` from api-core, which provides the `baseUrl`, `onRequest`, `retry`, and `cacheInstance` fields. `apiKey`, `businessId`, `region`, `cache`, and `rateLimitPerSecond` are EH-specific. Pass `cacheInstance` to use a custom cache backend (e.g., `LayeredCache` with persistent stores); otherwise `cache: {}` creates an in-memory `TTLCache`. PII data (`includePii: true`) automatically skips persistent stores.
159
+ `EHConfig` extends `ClientConfig` from api-core, which provides the `baseUrl`, `onRequest`, `retry`, and `cacheInstance` fields. `apiKey`, `businessId`, `region`, `cache`, and `rateLimitPerSecond` are EH-specific. Pass `cacheInstance` to use a custom cache backend (e.g., `LayeredCache` with persistent stores); otherwise `cache: {}` creates an in-memory `TTLCache`. Set `persistRestricted: false` to keep restricted-tier data in memory only.
176
160
 
177
161
  ### Cache TTLs
178
162
 
@@ -186,10 +170,8 @@ const client = new EHClient({
186
170
  | Leave requests | 2 min |
187
171
  | Kiosks | 5 min |
188
172
  | Kiosk staff | 1 min |
189
- | Report fields | 10 min |
190
- | Employee details report | 2 min |
191
173
 
192
- Failed API results (`ok: false`) are never cached — transient errors won't persist for the full TTL. See the [root README Cache System section](../../README.md#cache-system) for the full cache architecture (layered stores, PII handling, request coalescing).
174
+ Failed API results (`ok: false`) are never cached — transient errors won't persist for the full TTL. See the [root README Cache System section](../../README.md#cache-system) for the full cache architecture (layered stores, restricted data handling, request coalescing).
193
175
 
194
176
  ### Rate Limiting
195
177
 
package/dist/client.d.ts CHANGED
@@ -6,7 +6,7 @@
6
6
  *
7
7
  * @see https://api.keypay.com.au/
8
8
  */
9
- import type { EHConfig, EHLeaveRequest, EHLeaveRequestOptions, EHEmployeeOptions, EHSingleEmployeeOptions, EHStandardHours, EHLocation, EHEmployeeGroup, EHRosterShift, EHRosterShiftOptions, EHKiosk, EHKioskEmployee, EHKioskStaffOptions, EHReportField, EHEmployeeDetailsReportOptions } from './types.js';
9
+ import type { EHConfig, EHLeaveRequest, EHLeaveRequestOptions, EHEmployeeLeaveRequestOptions, EHEmployeeOptions, EHStandardHours, EHLocation, EHEmployeeGroup, EHRosterShift, EHRosterShiftOptions, EHKiosk, EHKioskEmployee, EHKioskStaffOptions } from './types.js';
10
10
  import type { EHAuEmployee } from './employee-types.generated.js';
11
11
  import type { Result } from '@markwharton/api-core';
12
12
  /**
@@ -36,16 +36,32 @@ export declare class EHClient {
36
36
  constructor(config: EHConfig);
37
37
  /** Cache options for restricted-tier methods: skip persistent stores when persistRestricted is false. */
38
38
  private get restrictedPersistOpt();
39
- /**
40
- * Route through cache if enabled, otherwise call factory directly.
41
- * Failed Results (ok === false) are never cached — transient errors
42
- * shouldn't persist for the full TTL.
43
- */
39
+ /** Route through cache if enabled, skipping failed Results. */
44
40
  private cached;
45
41
  /**
46
42
  * Clear all cached API responses.
47
43
  */
48
44
  clearCache(): void;
45
+ /**
46
+ * Invalidate cached employee data (employees, individual employees, standard hours).
47
+ */
48
+ invalidateEmployeeCache(): void;
49
+ /**
50
+ * Invalidate cached leave request data (business-level and per-employee).
51
+ */
52
+ invalidateLeaveRequestCache(): void;
53
+ /**
54
+ * Invalidate cached roster shift data.
55
+ */
56
+ invalidateRosterShiftCache(): void;
57
+ /**
58
+ * Invalidate cached location data.
59
+ */
60
+ invalidateLocationCache(): void;
61
+ /**
62
+ * Invalidate cached kiosk data (kiosks and kiosk staff).
63
+ */
64
+ invalidateKioskCache(): void;
49
65
  /**
50
66
  * Build a URL for a business-scoped endpoint.
51
67
  */
@@ -74,11 +90,11 @@ export declare class EHClient {
74
90
  */
75
91
  private fetchPaginated;
76
92
  /**
77
- * Validate the API key by calling GET /user
93
+ * Validate the API key
78
94
  */
79
95
  validateApiKey(): Promise<Result<void>>;
80
96
  /**
81
- * Get leave requests (server-side filtering)
97
+ * Get leave requests
82
98
  *
83
99
  * All filter options are passed as query parameters to the API.
84
100
  * The endpoint returns a flat array (not paginated).
@@ -87,13 +103,20 @@ export declare class EHClient {
87
103
  */
88
104
  getLeaveRequests(options?: EHLeaveRequestOptions): Promise<Result<EHLeaveRequest[]>>;
89
105
  /**
90
- * Get all employees (unstructured format)
106
+ * Get leave requests for a specific employee
107
+ *
108
+ * Uses the per-employee endpoint with OData pagination.
109
+ * Optional filters for status and date range.
110
+ */
111
+ getEmployeeLeaveRequests(employeeId: number, options?: EHEmployeeLeaveRequestOptions): Promise<Result<EHLeaveRequest[]>>;
112
+ /**
113
+ * Get all employees
91
114
  */
92
115
  getEmployees(options?: EHEmployeeOptions): Promise<Result<EHAuEmployee[]>>;
93
116
  /**
94
117
  * Get a single employee by ID
95
118
  */
96
- getEmployee(employeeId: number, options?: EHSingleEmployeeOptions): Promise<Result<EHAuEmployee>>;
119
+ getEmployee(employeeId: number): Promise<Result<EHAuEmployee>>;
97
120
  /**
98
121
  * Get standard hours for an employee (includes FTE value)
99
122
  */
@@ -125,18 +148,4 @@ export declare class EHClient {
125
148
  * @param options - Optional query parameters
126
149
  */
127
150
  getKioskStaff(kioskId: number, options?: EHKioskStaffOptions): Promise<Result<EHKioskEmployee[]>>;
128
- /**
129
- * Get available fields for the Employee Details Report
130
- *
131
- * Returns the list of columns that can be requested via getEmployeeDetailsReport().
132
- * Use this to discover what data is available for the business.
133
- */
134
- getReportFields(): Promise<Result<EHReportField[]>>;
135
- /**
136
- * Get Employee Details Report
137
- *
138
- * Returns all employees with the requested columns in a single API call.
139
- * The response is dynamic (JObject[]) — field keys depend on selectedColumns.
140
- */
141
- getEmployeeDetailsReport(options?: EHEmployeeDetailsReportOptions): Promise<Result<Record<string, unknown>[]>>;
142
151
  }
package/dist/client.js CHANGED
@@ -6,11 +6,11 @@
6
6
  *
7
7
  * @see https://api.keypay.com.au/
8
8
  */
9
- import { AU_EMPLOYEE_OPERATIONAL_FIELDS, AU_EMPLOYEE_FIELDS, LEAVE_REQUEST_FIELDS, LOCATION_FIELDS, EMPLOYEE_GROUP_FIELDS, ROSTER_SHIFT_FIELDS, KIOSK_FIELDS, KIOSK_EMPLOYEE_FIELDS, } from './types.js';
9
+ import { ENTITIES } from './types.js';
10
10
  import { buildBasicAuthHeader } from './utils.js';
11
11
  import { parseEHPayrollErrorResponse } from './errors.js';
12
12
  import { EH_API_BASE, EH_REGION_URLS } from './constants.js';
13
- import { TTLCache, pickFields, RateLimiter, getErrorMessage, fetchWithRetry, resolveRetryConfig, ok, okVoid, err } from '@markwharton/api-core';
13
+ import { pickFields, RateLimiter, getErrorMessage, fetchWithRetry, resolveRetryConfig, ok, okVoid, err, cachedResult, fetchAndParseResponse, resolveClientCache } from '@markwharton/api-core';
14
14
  /** Default page size for paginated endpoints */
15
15
  const DEFAULT_PAGE_SIZE = 100;
16
16
  // ============================================================================
@@ -37,9 +37,7 @@ export class EHClient {
37
37
  this.baseUrl = config.baseUrl ?? (config.region ? EH_REGION_URLS[config.region] : EH_API_BASE);
38
38
  this.onRequest = config.onRequest;
39
39
  // Initialize cache if configured
40
- if (config.cache || config.cacheInstance) {
41
- this.cache = config.cacheInstance ?? new TTLCache();
42
- }
40
+ this.cache = resolveClientCache(config);
43
41
  this.cacheTtl = {
44
42
  employeesTtl: config.cache?.employeesTtl ?? 300000,
45
43
  leaveRequestsTtl: config.cache?.leaveRequestsTtl ?? 120000,
@@ -49,8 +47,6 @@ export class EHClient {
49
47
  rosterShiftsTtl: config.cache?.rosterShiftsTtl ?? 120000,
50
48
  kiosksTtl: config.cache?.kiosksTtl ?? 300000,
51
49
  kioskStaffTtl: config.cache?.kioskStaffTtl ?? 60000,
52
- reportFieldsTtl: config.cache?.reportFieldsTtl ?? 600000,
53
- employeeDetailsReportTtl: config.cache?.employeeDetailsReportTtl ?? 120000,
54
50
  };
55
51
  // Initialize retry config with defaults if provided
56
52
  this.retryConfig = resolveRetryConfig(config.retry);
@@ -65,18 +61,9 @@ export class EHClient {
65
61
  get restrictedPersistOpt() {
66
62
  return this.persistRestricted ? undefined : { persist: false };
67
63
  }
68
- /**
69
- * Route through cache if enabled, otherwise call factory directly.
70
- * Failed Results (ok === false) are never cached — transient errors
71
- * shouldn't persist for the full TTL.
72
- */
73
- async cached(key, ttlMs, factory, options) {
74
- if (!this.cache)
75
- return factory();
76
- return this.cache.get(key, ttlMs, factory, {
77
- ...options,
78
- shouldCache: (data) => data.ok !== false,
79
- });
64
+ /** Route through cache if enabled, skipping failed Results. */
65
+ cached(key, ttlMs, factory, options) {
66
+ return cachedResult(this.cache, key, ttlMs, factory, options);
80
67
  }
81
68
  /**
82
69
  * Clear all cached API responses.
@@ -84,6 +71,40 @@ export class EHClient {
84
71
  clearCache() {
85
72
  this.cache?.clear();
86
73
  }
74
+ /**
75
+ * Invalidate cached employee data (employees, individual employees, standard hours).
76
+ */
77
+ invalidateEmployeeCache() {
78
+ this.cache?.invalidate('employees');
79
+ this.cache?.invalidate('employee:');
80
+ this.cache?.invalidate('standardhours:');
81
+ }
82
+ /**
83
+ * Invalidate cached leave request data (business-level and per-employee).
84
+ */
85
+ invalidateLeaveRequestCache() {
86
+ this.cache?.invalidate('leaverequests');
87
+ this.cache?.invalidate('employeeleaverequests:');
88
+ }
89
+ /**
90
+ * Invalidate cached roster shift data.
91
+ */
92
+ invalidateRosterShiftCache() {
93
+ this.cache?.invalidate('rostershifts:');
94
+ }
95
+ /**
96
+ * Invalidate cached location data.
97
+ */
98
+ invalidateLocationCache() {
99
+ this.cache?.invalidate('locations');
100
+ }
101
+ /**
102
+ * Invalidate cached kiosk data (kiosks and kiosk staff).
103
+ */
104
+ invalidateKioskCache() {
105
+ this.cache?.invalidate('kiosks');
106
+ this.cache?.invalidate('kiosk:');
107
+ }
87
108
  /**
88
109
  * Build a URL for a business-scoped endpoint.
89
110
  */
@@ -128,19 +149,8 @@ export class EHClient {
128
149
  /**
129
150
  * Fetch a URL and parse the response, with standardized error handling.
130
151
  */
131
- async fetchAndParse(url, parse, fetchOptions) {
132
- try {
133
- const response = await this.fetch(url, fetchOptions);
134
- if (!response.ok) {
135
- const errorText = await response.text();
136
- const { message } = parseEHPayrollErrorResponse(errorText, response.status);
137
- return err(message, response.status);
138
- }
139
- return ok(await parse(response));
140
- }
141
- catch (error) {
142
- return err(getErrorMessage(error), 0);
143
- }
152
+ fetchAndParse(url, parse, fetchOptions) {
153
+ return fetchAndParseResponse(() => this.fetch(url, fetchOptions), parse, parseEHPayrollErrorResponse);
144
154
  }
145
155
  /**
146
156
  * Fetch all pages of a paginated endpoint.
@@ -182,7 +192,7 @@ export class EHClient {
182
192
  // Validation
183
193
  // ============================================================================
184
194
  /**
185
- * Validate the API key by calling GET /user
195
+ * Validate the API key
186
196
  */
187
197
  async validateApiKey() {
188
198
  const url = `${this.baseUrl}/user`;
@@ -204,7 +214,7 @@ export class EHClient {
204
214
  // Leave Requests
205
215
  // ============================================================================
206
216
  /**
207
- * Get leave requests (server-side filtering)
217
+ * Get leave requests
208
218
  *
209
219
  * All filter options are passed as query parameters to the API.
210
220
  * The endpoint returns a flat array (not paginated).
@@ -240,30 +250,60 @@ export class EHClient {
240
250
  params.set('LeaveCategoryId', String(options.leaveCategoryId));
241
251
  if (options?.locationId != null)
242
252
  params.set('LocationId', String(options.locationId));
243
- const url = this.businessUrl('leaverequest', params);
253
+ const url = this.businessUrl(ENTITIES.EHLeaveRequest.path, params);
244
254
  return this.fetchAndParse(url, async (r) => {
245
255
  return (await r.json())
246
- .map(item => pickFields(item, LEAVE_REQUEST_FIELDS));
256
+ .map(item => pickFields(item, ENTITIES.EHLeaveRequest.fields));
247
257
  });
248
258
  }, this.restrictedPersistOpt);
249
259
  }
260
+ /**
261
+ * Get leave requests for a specific employee
262
+ *
263
+ * Uses the per-employee endpoint with OData pagination.
264
+ * Optional filters for status and date range.
265
+ */
266
+ async getEmployeeLeaveRequests(employeeId, options) {
267
+ const parts = [`employeeleaverequests:${employeeId}`];
268
+ if (options?.status)
269
+ parts.push(`s:${options.status}`);
270
+ if (options?.fromDate)
271
+ parts.push(`from:${options.fromDate}`);
272
+ if (options?.toDate)
273
+ parts.push(`to:${options.toDate}`);
274
+ const cacheKey = parts.join(':');
275
+ const entityPath = ENTITIES.EHEmployeeLeaveRequest.path.replace('{employeeId}', String(employeeId));
276
+ return this.cached(cacheKey, this.cacheTtl.leaveRequestsTtl, () => {
277
+ const params = new URLSearchParams();
278
+ params.set('$top', String(DEFAULT_PAGE_SIZE));
279
+ const filterParts = [];
280
+ if (options?.status)
281
+ filterParts.push(`Status eq '${options.status}'`);
282
+ if (options?.fromDate)
283
+ filterParts.push(`FromDate ge datetime'${options.fromDate}'`);
284
+ if (options?.toDate)
285
+ filterParts.push(`ToDate le datetime'${options.toDate}'`);
286
+ if (filterParts.length > 0)
287
+ params.set('$filter', filterParts.join(' and '));
288
+ return this.fetchPaginated((skip) => {
289
+ params.set('$skip', String(skip));
290
+ return this.businessUrl(entityPath, params);
291
+ }, ENTITIES.EHEmployeeLeaveRequest.fields);
292
+ }, this.restrictedPersistOpt);
293
+ }
250
294
  // ============================================================================
251
295
  // Employees
252
296
  // ============================================================================
253
297
  /**
254
- * Get all employees (unstructured format)
298
+ * Get all employees
255
299
  */
256
300
  async getEmployees(options) {
257
- const fields = options?.includePii ? AU_EMPLOYEE_FIELDS : AU_EMPLOYEE_OPERATIONAL_FIELDS;
258
301
  const parts = ['employees'];
259
302
  if (options?.payScheduleId != null)
260
303
  parts.push(`ps:${options.payScheduleId}`);
261
304
  if (options?.locationId != null)
262
305
  parts.push(`loc:${options.locationId}`);
263
- if (options?.includePii)
264
- parts.push('pii');
265
306
  const cacheKey = parts.join(':');
266
- const persistOpt = (options?.includePii || !this.persistRestricted) ? { persist: false } : undefined;
267
307
  return this.cached(cacheKey, this.cacheTtl.employeesTtl, () => {
268
308
  const params = new URLSearchParams();
269
309
  if (options?.payScheduleId != null)
@@ -273,23 +313,20 @@ export class EHClient {
273
313
  params.set('$top', String(DEFAULT_PAGE_SIZE));
274
314
  return this.fetchPaginated((skip) => {
275
315
  params.set('$skip', String(skip));
276
- return `${this.baseUrl}/business/${this.businessId}/employee/unstructured?${params}`;
277
- }, fields);
278
- }, persistOpt);
316
+ return this.businessUrl(ENTITIES.EHAuEmployee.path, params);
317
+ }, ENTITIES.EHAuEmployee.fields);
318
+ }, this.restrictedPersistOpt);
279
319
  }
280
320
  /**
281
321
  * Get a single employee by ID
282
322
  */
283
- async getEmployee(employeeId, options) {
284
- const fields = options?.includePii ? AU_EMPLOYEE_FIELDS : AU_EMPLOYEE_OPERATIONAL_FIELDS;
285
- const cacheKey = options?.includePii ? `employee:${employeeId}:pii` : `employee:${employeeId}`;
286
- const persistOpt = (options?.includePii || !this.persistRestricted) ? { persist: false } : undefined;
287
- return this.cached(cacheKey, this.cacheTtl.employeesTtl, async () => {
288
- const url = `${this.baseUrl}/business/${this.businessId}/employee/unstructured/${employeeId}`;
323
+ async getEmployee(employeeId) {
324
+ return this.cached(`employee:${employeeId}`, this.cacheTtl.employeesTtl, async () => {
325
+ const url = this.businessUrl(`${ENTITIES.EHAuEmployee.path}/${employeeId}`);
289
326
  return this.fetchAndParse(url, async (r) => {
290
- return pickFields(await r.json(), fields);
327
+ return pickFields(await r.json(), ENTITIES.EHAuEmployee.fields);
291
328
  });
292
- }, persistOpt);
329
+ }, this.restrictedPersistOpt);
293
330
  }
294
331
  // ============================================================================
295
332
  // Standard Hours
@@ -316,8 +353,8 @@ export class EHClient {
316
353
  const params = new URLSearchParams({ '$top': String(DEFAULT_PAGE_SIZE) });
317
354
  return this.fetchPaginated((skip) => {
318
355
  params.set('$skip', String(skip));
319
- return `${this.baseUrl}/business/${this.businessId}/location?${params}`;
320
- }, LOCATION_FIELDS);
356
+ return this.businessUrl(ENTITIES.EHLocation.path, params);
357
+ }, ENTITIES.EHLocation.fields);
321
358
  });
322
359
  }
323
360
  // ============================================================================
@@ -331,8 +368,8 @@ export class EHClient {
331
368
  const params = new URLSearchParams({ '$top': String(DEFAULT_PAGE_SIZE) });
332
369
  return this.fetchPaginated((skip) => {
333
370
  params.set('$skip', String(skip));
334
- return `${this.baseUrl}/business/${this.businessId}/employeegroup?${params}`;
335
- }, EMPLOYEE_GROUP_FIELDS);
371
+ return this.businessUrl(ENTITIES.EHEmployeeGroup.path, params);
372
+ }, ENTITIES.EHEmployeeGroup.fields);
336
373
  });
337
374
  }
338
375
  // ============================================================================
@@ -414,8 +451,8 @@ export class EHClient {
414
451
  params.set('IncludeWarnings', 'true');
415
452
  return this.fetchPaginated((skip) => {
416
453
  params.set('CurrentPage', String(skip / DEFAULT_PAGE_SIZE + 1));
417
- return `${this.baseUrl}/business/${this.businessId}/rostershift?${params}`;
418
- }, ROSTER_SHIFT_FIELDS);
454
+ return this.businessUrl(ENTITIES.EHRosterShift.path, params);
455
+ }, ENTITIES.EHRosterShift.fields);
419
456
  });
420
457
  }
421
458
  // ============================================================================
@@ -429,8 +466,8 @@ export class EHClient {
429
466
  const params = new URLSearchParams({ '$top': String(DEFAULT_PAGE_SIZE) });
430
467
  return this.fetchPaginated((skip) => {
431
468
  params.set('$skip', String(skip));
432
- return `${this.baseUrl}/business/${this.businessId}/kiosk?${params}`;
433
- }, KIOSK_FIELDS);
469
+ return this.businessUrl(ENTITIES.EHKiosk.path, params);
470
+ }, ENTITIES.EHKiosk.fields);
434
471
  });
435
472
  }
436
473
  /**
@@ -448,68 +485,11 @@ export class EHClient {
448
485
  if (options?.restrictCurrentShiftsToCurrentKioskLocation) {
449
486
  params.set('restrictCurrentShiftsToCurrentKioskLocation', 'true');
450
487
  }
451
- const url = this.businessUrl(`kiosk/${kioskId}/staff`, params);
488
+ const url = this.businessUrl(ENTITIES.EHKioskEmployee.path.replace('{kioskId}', String(kioskId)), params);
452
489
  return this.fetchAndParse(url, async (r) => {
453
490
  return (await r.json())
454
- .map(item => pickFields(item, KIOSK_EMPLOYEE_FIELDS));
491
+ .map(item => pickFields(item, ENTITIES.EHKioskEmployee.fields));
455
492
  });
456
493
  });
457
494
  }
458
- // ============================================================================
459
- // Employee Details Report
460
- // ============================================================================
461
- /**
462
- * Get available fields for the Employee Details Report
463
- *
464
- * Returns the list of columns that can be requested via getEmployeeDetailsReport().
465
- * Use this to discover what data is available for the business.
466
- */
467
- async getReportFields() {
468
- return this.cached('reportfields', this.cacheTtl.reportFieldsTtl, async () => {
469
- const url = `${this.baseUrl}/business/${this.businessId}/report/employeedetails/fields`;
470
- return this.fetchAndParse(url, async (r) => {
471
- return await r.json();
472
- });
473
- });
474
- }
475
- /**
476
- * Get Employee Details Report
477
- *
478
- * Returns all employees with the requested columns in a single API call.
479
- * The response is dynamic (JObject[]) — field keys depend on selectedColumns.
480
- */
481
- async getEmployeeDetailsReport(options) {
482
- const parts = ['report:employeedetails'];
483
- if (options?.selectedColumns?.length)
484
- parts.push(`cols:${options.selectedColumns.join(',')}`);
485
- if (options?.locationId != null)
486
- parts.push(`loc:${options.locationId}`);
487
- if (options?.employingEntityId != null)
488
- parts.push(`ee:${options.employingEntityId}`);
489
- if (options?.includeActive != null)
490
- parts.push(`a:${options.includeActive}`);
491
- if (options?.includeInactive != null)
492
- parts.push(`i:${options.includeInactive}`);
493
- const cacheKey = parts.join(':');
494
- return this.cached(cacheKey, this.cacheTtl.employeeDetailsReportTtl, async () => {
495
- const params = new URLSearchParams();
496
- if (options?.selectedColumns) {
497
- for (const col of options.selectedColumns) {
498
- params.append('selectedColumns', col);
499
- }
500
- }
501
- if (options?.locationId != null)
502
- params.set('locationId', String(options.locationId));
503
- if (options?.employingEntityId != null)
504
- params.set('employingEntityId', String(options.employingEntityId));
505
- if (options?.includeActive != null)
506
- params.set('includeActive', String(options.includeActive));
507
- if (options?.includeInactive != null)
508
- params.set('includeInactive', String(options.includeInactive));
509
- const url = this.businessUrl('report/employeedetails', params);
510
- return this.fetchAndParse(url, async (r) => {
511
- return await r.json();
512
- });
513
- }, this.restrictedPersistOpt);
514
- }
515
495
  }
package/dist/index.d.ts CHANGED
@@ -20,8 +20,8 @@
20
20
  * ```
21
21
  */
22
22
  export { EHClient } from './client.js';
23
- export type { EHConfig, EHCacheConfig, EHRetryConfig, EHLeaveRequest, EHLeaveRequestOptions, EHLeaveRequestStatus, EHEmployee, EHEmployeeOptions, EHSingleEmployeeOptions, EHStandardHours, EHLocation, EHEmployeeGroup, EHRosterShift, EHRosterShiftOptions, EHAttendanceStatus, EHKiosk, EHKioskEmployee, EHKioskStaffOptions, EHReportField, EHEmployeeDetailsReportOptions, } from './types.js';
24
- export { AU_EMPLOYEE_OPERATIONAL_FIELDS, AU_EMPLOYEE_PII_FIELDS, AU_EMPLOYEE_FIELDS, LEAVE_REQUEST_FIELDS, LOCATION_FIELDS, EMPLOYEE_GROUP_FIELDS, ROSTER_SHIFT_FIELDS, KIOSK_FIELDS, KIOSK_EMPLOYEE_FIELDS, } from './types.js';
23
+ export type { EHConfig, EHCacheConfig, EHRetryConfig, EHLeaveRequest, EHLeaveRequestOptions, EHEmployeeLeaveRequestOptions, EHLeaveRequestStatus, EHEmployee, EHEmployeeOptions, EHStandardHours, EHLocation, EHEmployeeGroup, EHRosterShift, EHRosterShiftOptions, EHAttendanceStatus, EHKiosk, EHKioskEmployee, EHKioskStaffOptions, } from './types.js';
24
+ export { AU_EMPLOYEE_FIELDS, LEAVE_REQUEST_FIELDS, LOCATION_FIELDS, EMPLOYEE_GROUP_FIELDS, ROSTER_SHIFT_FIELDS, KIOSK_FIELDS, KIOSK_EMPLOYEE_FIELDS, ENTITIES, } from './types.js';
25
25
  export type { AccessTier } from './types.js';
26
26
  export { METHOD_TIERS } from './types.js';
27
27
  export type { EHAuEmployee } from './employee-types.generated.js';
package/dist/index.js CHANGED
@@ -21,8 +21,8 @@
21
21
  */
22
22
  // Main client
23
23
  export { EHClient } from './client.js';
24
- // Field key constants (whitelists for pickFields)
25
- export { AU_EMPLOYEE_OPERATIONAL_FIELDS, AU_EMPLOYEE_PII_FIELDS, AU_EMPLOYEE_FIELDS, LEAVE_REQUEST_FIELDS, LOCATION_FIELDS, EMPLOYEE_GROUP_FIELDS, ROSTER_SHIFT_FIELDS, KIOSK_FIELDS, KIOSK_EMPLOYEE_FIELDS, } from './types.js';
24
+ // Field definitions (for pickFields)
25
+ export { AU_EMPLOYEE_FIELDS, LEAVE_REQUEST_FIELDS, LOCATION_FIELDS, EMPLOYEE_GROUP_FIELDS, ROSTER_SHIFT_FIELDS, KIOSK_FIELDS, KIOSK_EMPLOYEE_FIELDS, ENTITIES, } from './types.js';
26
26
  export { METHOD_TIERS } from './types.js';
27
27
  // Utilities
28
28
  export { buildBasicAuthHeader } from './utils.js';
package/dist/types.d.ts CHANGED
@@ -29,10 +29,6 @@ export interface EHCacheConfig {
29
29
  kiosksTtl?: number;
30
30
  /** TTL for kiosk staff (default: 60000 = 1 min) */
31
31
  kioskStaffTtl?: number;
32
- /** TTL for report fields (default: 600000 = 10 min) */
33
- reportFieldsTtl?: number;
34
- /** TTL for employee details report (default: 120000 = 2 min) */
35
- employeeDetailsReportTtl?: number;
36
32
  }
37
33
  /** @deprecated Use `RetryConfig` from `@markwharton/api-core` directly. */
38
34
  export type EHRetryConfig = RetryConfig;
@@ -182,7 +178,7 @@ export interface EHKioskEmployee {
182
178
  * Leave request from the Payroll API
183
179
  *
184
180
  * From GET /business/{id}/leaverequest
185
- * Field whitelist from Swagger HourLeaveRequestResponseModel.
181
+ * Fields from Swagger HourLeaveRequestResponseModel.
186
182
  */
187
183
  export interface EHLeaveRequest {
188
184
  /** Leave request ID */
@@ -229,6 +225,19 @@ export interface EHLeaveRequestOptions {
229
225
  /** Filter by location ID (→ API LocationId) */
230
226
  locationId?: number;
231
227
  }
228
+ /**
229
+ * Options for getEmployeeLeaveRequests
230
+ *
231
+ * Filters are passed as OData $filter to the per-employee endpoint.
232
+ */
233
+ export interface EHEmployeeLeaveRequestOptions {
234
+ /** Filter by status */
235
+ status?: EHLeaveRequestStatus;
236
+ /** Filter by start date (ISO 8601 date-time) */
237
+ fromDate?: string;
238
+ /** Filter by end date (ISO 8601 date-time) */
239
+ toDate?: string;
240
+ }
232
241
  /**
233
242
  * Options for getEmployees
234
243
  */
@@ -237,15 +246,6 @@ export interface EHEmployeeOptions {
237
246
  payScheduleId?: number;
238
247
  /** Filter by location ID */
239
248
  locationId?: number;
240
- /** Include PII fields (default: false — operational fields only) */
241
- includePii?: boolean;
242
- }
243
- /**
244
- * Options for getEmployee (single)
245
- */
246
- export interface EHSingleEmployeeOptions {
247
- /** Include PII fields (default: false — operational fields only) */
248
- includePii?: boolean;
249
249
  }
250
250
  /**
251
251
  * Options for getRosterShifts
@@ -322,63 +322,238 @@ export interface EHKioskStaffOptions {
322
322
  /** Restrict current shifts to current kiosk location (default: false) */
323
323
  restrictCurrentShiftsToCurrentKioskLocation?: boolean;
324
324
  }
325
- /**
326
- * Available field for the Employee Details Report
327
- *
328
- * From GET /business/{id}/report/employeedetails/fields
329
- */
330
- export interface EHReportField {
331
- /** Field identifier (used in selectedColumns) */
332
- value: string;
333
- /** Human-readable field name */
334
- displayText: string;
335
- }
336
- /**
337
- * Options for getEmployeeDetailsReport
338
- */
339
- export interface EHEmployeeDetailsReportOptions {
340
- /** Column names to include in the report */
341
- selectedColumns?: string[];
342
- /** Filter by location ID */
343
- locationId?: number;
344
- /** Filter by employing entity ID */
345
- employingEntityId?: number;
346
- /** Include active employees (default: true) */
347
- includeActive?: boolean;
348
- /** Include inactive employees (default: false) */
349
- includeInactive?: boolean;
350
- }
351
- /** Whitelisted fields for EHLeaveRequest */
352
- export declare const LEAVE_REQUEST_FIELDS: readonly ["id", "employeeId", "leaveCategoryId", "employee", "leaveCategory", "fromDate", "toDate", "totalHours", "hoursApplied", "notes", "status"];
353
- /** Whitelisted fields for EHLocation */
354
- export declare const LOCATION_FIELDS: readonly ["id", "parentId", "name", "externalId", "source", "fullyQualifiedName", "isGlobal", "state", "country"];
355
- /** Whitelisted fields for EHKiosk */
356
- export declare const KIOSK_FIELDS: readonly ["id", "externalId", "name", "locationId", "timeZone", "ianaTimeZone", "allowHigherClassificationSelection", "isLocationRequired", "isWorkTypeRequired", "restrictLocationsForEmployees", "allowEmployeeShiftSelection", "clockOnWindowMinutes", "clockOffWindowMinutes", "isPhotoRequired", "canAddEmployees", "paidBreaksEnabled"];
357
- /** Whitelisted fields for EHKioskEmployee */
358
- export declare const KIOSK_EMPLOYEE_FIELDS: readonly ["employeeId", "firstName", "surname", "name", "status", "clockOnTimeUtc", "breakStartTimeUtc", "currentShiftId", "employeeStartDate", "employeeGroupIds", "longShift", "recordedTimeUtc"];
359
- /** Whitelisted fields for EHEmployeeGroup */
360
- export declare const EMPLOYEE_GROUP_FIELDS: readonly ["id", "name"];
361
- /** Whitelisted fields for EHRosterShift */
362
- export declare const ROSTER_SHIFT_FIELDS: readonly ["id", "employeeId", "employeeName", "locationId", "locationName", "workTypeId", "workTypeName", "startTime", "endTime", "notes", "published", "accepted"];
363
- /**
364
- * Operational fields for EHAuEmployee (52 fields)
365
- * Identity, employment structure, pay config, scheduling, leave, AU compliance.
366
- */
367
- export declare const AU_EMPLOYEE_OPERATIONAL_FIELDS: readonly ["id", "externalId", "firstName", "surname", "status", "startDate", "endDate", "anniversaryDate", "dateCreated", "employmentType", "jobTitle", "employmentAgreement", "employmentAgreementId", "paySchedule", "payRateTemplate", "rate", "rateUnit", "hoursPerWeek", "hoursPerDay", "primaryPayCategory", "payConditionRuleSet", "overrideTemplateRate", "automaticallyPayEmployee", "primaryLocation", "locations", "tags", "workTypes", "reportingDimensionValues", "leaveAccrualStartDateType", "leaveTemplate", "leaveYearStart", "isEnabledForTimesheets", "rosteringNotificationChoices", "paySlipNotificationType", "terminationReason", "australianResident", "awardId", "businessAwardPackage", "automaticallyApplyPublicHolidayNotWorkedEarningsLines", "closelyHeldEmployee", "closelyHeldReporting", "disableAutoProgression", "dvlPaySlipDescription", "employingEntityId", "includeInPortableLongServiceLeaveReport", "portableLongServiceLeaveId", "isExemptFromFloodLevy", "isExemptFromPayrollTax", "isSeasonalWorker", "maximumQuarterlySuperContributionsBase", "superThresholdAmount", "singleTouchPayroll"];
368
- /**
369
- * PII fields for EHAuEmployee (87 fields)
370
- * Personal data, contact info, bank accounts, addresses, tax, super, emergency contacts.
371
- */
372
- export declare const AU_EMPLOYEE_PII_FIELDS: readonly ["dateOfBirth", "gender", "title", "middleName", "preferredName", "previousSurname", "emailAddress", "homePhone", "mobilePhone", "workPhone", "bankAccount1_AccountName", "bankAccount1_AccountNumber", "bankAccount1_AllocatedPercentage", "bankAccount1_BSB", "bankAccount1_FixedAmount", "bankAccount2_AccountName", "bankAccount2_AccountNumber", "bankAccount2_AllocatedPercentage", "bankAccount2_BSB", "bankAccount2_FixedAmount", "bankAccount3_AccountName", "bankAccount3_AccountNumber", "bankAccount3_AllocatedPercentage", "bankAccount3_BSB", "bankAccount3_FixedAmount", "emergencyContact1_Address", "emergencyContact1_AlternateContactNumber", "emergencyContact1_ContactNumber", "emergencyContact1_Name", "emergencyContact1_Relationship", "emergencyContact2_Address", "emergencyContact2_AlternateContactNumber", "emergencyContact2_ContactNumber", "emergencyContact2_Name", "emergencyContact2_Relationship", "postalStreetAddress", "postalAddressLine2", "postalPostCode", "postalCountry", "postalState", "postalSuburb", "postalAddressIsOverseas", "residentialStreetAddress", "residentialAddressLine2", "residentialPostCode", "residentialCountry", "residentialState", "residentialSuburb", "residentialAddressIsOverseas", "taxFileNumber", "taxCategory", "taxVariation", "claimTaxFreeThreshold", "claimMedicareLevyReduction", "medicareLevyExemption", "medicareLevyReductionDependentCount", "medicareLevyReductionSpouse", "medicareLevySurchargeWithholdingTier", "seniorsTaxOffset", "otherTaxOffset", "stslDebt", "hasWithholdingVariation", "dateTaxFileDeclarationReported", "dateTaxFileDeclarationSigned", "superFund1_AllocatedPercentage", "superFund1_EmployerNominatedFund", "superFund1_FixedAmount", "superFund1_FundName", "superFund1_MemberNumber", "superFund1_ProductCode", "superFund2_AllocatedPercentage", "superFund2_EmployerNominatedFund", "superFund2_FixedAmount", "superFund2_FundName", "superFund2_MemberNumber", "superFund2_ProductCode", "superFund3_AllocatedPercentage", "superFund3_EmployerNominatedFund", "superFund3_FixedAmount", "superFund3_FundName", "superFund3_MemberNumber", "superFund3_ProductCode", "contractorABN", "employingEntityABN", "hasApprovedWorkingHolidayVisa", "workingHolidayVisaCountry", "workingHolidayVisaStartDate"];
373
- /** All whitelisted fields for EHAuEmployee (operational + PII) */
374
- export declare const AU_EMPLOYEE_FIELDS: readonly ["id", "externalId", "firstName", "surname", "status", "startDate", "endDate", "anniversaryDate", "dateCreated", "employmentType", "jobTitle", "employmentAgreement", "employmentAgreementId", "paySchedule", "payRateTemplate", "rate", "rateUnit", "hoursPerWeek", "hoursPerDay", "primaryPayCategory", "payConditionRuleSet", "overrideTemplateRate", "automaticallyPayEmployee", "primaryLocation", "locations", "tags", "workTypes", "reportingDimensionValues", "leaveAccrualStartDateType", "leaveTemplate", "leaveYearStart", "isEnabledForTimesheets", "rosteringNotificationChoices", "paySlipNotificationType", "terminationReason", "australianResident", "awardId", "businessAwardPackage", "automaticallyApplyPublicHolidayNotWorkedEarningsLines", "closelyHeldEmployee", "closelyHeldReporting", "disableAutoProgression", "dvlPaySlipDescription", "employingEntityId", "includeInPortableLongServiceLeaveReport", "portableLongServiceLeaveId", "isExemptFromFloodLevy", "isExemptFromPayrollTax", "isSeasonalWorker", "maximumQuarterlySuperContributionsBase", "superThresholdAmount", "singleTouchPayroll", "dateOfBirth", "gender", "title", "middleName", "preferredName", "previousSurname", "emailAddress", "homePhone", "mobilePhone", "workPhone", "bankAccount1_AccountName", "bankAccount1_AccountNumber", "bankAccount1_AllocatedPercentage", "bankAccount1_BSB", "bankAccount1_FixedAmount", "bankAccount2_AccountName", "bankAccount2_AccountNumber", "bankAccount2_AllocatedPercentage", "bankAccount2_BSB", "bankAccount2_FixedAmount", "bankAccount3_AccountName", "bankAccount3_AccountNumber", "bankAccount3_AllocatedPercentage", "bankAccount3_BSB", "bankAccount3_FixedAmount", "emergencyContact1_Address", "emergencyContact1_AlternateContactNumber", "emergencyContact1_ContactNumber", "emergencyContact1_Name", "emergencyContact1_Relationship", "emergencyContact2_Address", "emergencyContact2_AlternateContactNumber", "emergencyContact2_ContactNumber", "emergencyContact2_Name", "emergencyContact2_Relationship", "postalStreetAddress", "postalAddressLine2", "postalPostCode", "postalCountry", "postalState", "postalSuburb", "postalAddressIsOverseas", "residentialStreetAddress", "residentialAddressLine2", "residentialPostCode", "residentialCountry", "residentialState", "residentialSuburb", "residentialAddressIsOverseas", "taxFileNumber", "taxCategory", "taxVariation", "claimTaxFreeThreshold", "claimMedicareLevyReduction", "medicareLevyExemption", "medicareLevyReductionDependentCount", "medicareLevyReductionSpouse", "medicareLevySurchargeWithholdingTier", "seniorsTaxOffset", "otherTaxOffset", "stslDebt", "hasWithholdingVariation", "dateTaxFileDeclarationReported", "dateTaxFileDeclarationSigned", "superFund1_AllocatedPercentage", "superFund1_EmployerNominatedFund", "superFund1_FixedAmount", "superFund1_FundName", "superFund1_MemberNumber", "superFund1_ProductCode", "superFund2_AllocatedPercentage", "superFund2_EmployerNominatedFund", "superFund2_FixedAmount", "superFund2_FundName", "superFund2_MemberNumber", "superFund2_ProductCode", "superFund3_AllocatedPercentage", "superFund3_EmployerNominatedFund", "superFund3_FixedAmount", "superFund3_FundName", "superFund3_MemberNumber", "superFund3_ProductCode", "contractorABN", "employingEntityABN", "hasApprovedWorkingHolidayVisa", "workingHolidayVisaCountry", "workingHolidayVisaStartDate"];
325
+ /** Fields for EHLeaveRequest — set false to exclude from API responses */
326
+ export declare const LEAVE_REQUEST_FIELDS: {
327
+ readonly id: true;
328
+ readonly employeeId: true;
329
+ readonly leaveCategoryId: true;
330
+ readonly employee: true;
331
+ readonly leaveCategory: true;
332
+ readonly fromDate: true;
333
+ readonly toDate: true;
334
+ readonly totalHours: true;
335
+ readonly hoursApplied: true;
336
+ readonly notes: true;
337
+ readonly status: true;
338
+ };
339
+ /** Fields for EHLocation — set false to exclude from API responses */
340
+ export declare const LOCATION_FIELDS: {
341
+ readonly id: true;
342
+ readonly parentId: true;
343
+ readonly name: true;
344
+ readonly externalId: true;
345
+ readonly source: true;
346
+ readonly fullyQualifiedName: true;
347
+ readonly isGlobal: true;
348
+ readonly state: true;
349
+ readonly country: true;
350
+ };
351
+ /** Fields for EHKiosk — set false to exclude from API responses */
352
+ export declare const KIOSK_FIELDS: {
353
+ readonly id: true;
354
+ readonly externalId: true;
355
+ readonly name: true;
356
+ readonly locationId: true;
357
+ readonly timeZone: true;
358
+ readonly ianaTimeZone: true;
359
+ readonly allowHigherClassificationSelection: true;
360
+ readonly isLocationRequired: true;
361
+ readonly isWorkTypeRequired: true;
362
+ readonly restrictLocationsForEmployees: true;
363
+ readonly allowEmployeeShiftSelection: true;
364
+ readonly clockOnWindowMinutes: true;
365
+ readonly clockOffWindowMinutes: true;
366
+ readonly isPhotoRequired: true;
367
+ readonly canAddEmployees: true;
368
+ readonly paidBreaksEnabled: true;
369
+ };
370
+ /** Fields for EHKioskEmployee set false to exclude from API responses */
371
+ export declare const KIOSK_EMPLOYEE_FIELDS: {
372
+ readonly employeeId: true;
373
+ readonly firstName: true;
374
+ readonly surname: true;
375
+ readonly name: true;
376
+ readonly status: true;
377
+ readonly clockOnTimeUtc: true;
378
+ readonly breakStartTimeUtc: true;
379
+ readonly currentShiftId: true;
380
+ readonly employeeStartDate: true;
381
+ readonly employeeGroupIds: true;
382
+ readonly longShift: true;
383
+ readonly recordedTimeUtc: true;
384
+ };
385
+ /** Fields for EHEmployeeGroup — set false to exclude from API responses */
386
+ export declare const EMPLOYEE_GROUP_FIELDS: {
387
+ readonly id: true;
388
+ readonly name: true;
389
+ };
390
+ /** Fields for EHRosterShift — set false to exclude from API responses */
391
+ export declare const ROSTER_SHIFT_FIELDS: {
392
+ readonly id: true;
393
+ readonly employeeId: true;
394
+ readonly employeeName: true;
395
+ readonly locationId: true;
396
+ readonly locationName: true;
397
+ readonly workTypeId: true;
398
+ readonly workTypeName: true;
399
+ readonly startTime: true;
400
+ readonly endTime: true;
401
+ readonly notes: true;
402
+ readonly published: true;
403
+ readonly accepted: true;
404
+ };
405
+ /** Fields for EHAuEmployee — set false to exclude from API responses */
406
+ export declare const AU_EMPLOYEE_FIELDS: {
407
+ readonly id: true;
408
+ readonly externalId: true;
409
+ readonly firstName: true;
410
+ readonly surname: true;
411
+ readonly status: true;
412
+ readonly startDate: true;
413
+ readonly endDate: true;
414
+ readonly anniversaryDate: false;
415
+ readonly dateCreated: false;
416
+ readonly employmentType: true;
417
+ readonly jobTitle: true;
418
+ readonly employmentAgreement: false;
419
+ readonly employmentAgreementId: false;
420
+ readonly paySchedule: false;
421
+ readonly payRateTemplate: false;
422
+ readonly rate: false;
423
+ readonly rateUnit: false;
424
+ readonly hoursPerWeek: false;
425
+ readonly hoursPerDay: false;
426
+ readonly primaryPayCategory: false;
427
+ readonly payConditionRuleSet: false;
428
+ readonly overrideTemplateRate: false;
429
+ readonly automaticallyPayEmployee: false;
430
+ readonly primaryLocation: true;
431
+ readonly locations: false;
432
+ readonly tags: false;
433
+ readonly workTypes: false;
434
+ readonly reportingDimensionValues: false;
435
+ readonly leaveAccrualStartDateType: false;
436
+ readonly leaveTemplate: false;
437
+ readonly leaveYearStart: false;
438
+ readonly isEnabledForTimesheets: false;
439
+ readonly rosteringNotificationChoices: false;
440
+ readonly paySlipNotificationType: false;
441
+ readonly terminationReason: false;
442
+ readonly australianResident: false;
443
+ readonly awardId: false;
444
+ readonly businessAwardPackage: false;
445
+ readonly automaticallyApplyPublicHolidayNotWorkedEarningsLines: false;
446
+ readonly closelyHeldEmployee: false;
447
+ readonly closelyHeldReporting: false;
448
+ readonly disableAutoProgression: false;
449
+ readonly dvlPaySlipDescription: false;
450
+ readonly employingEntityId: false;
451
+ readonly includeInPortableLongServiceLeaveReport: false;
452
+ readonly portableLongServiceLeaveId: false;
453
+ readonly isExemptFromFloodLevy: false;
454
+ readonly isExemptFromPayrollTax: false;
455
+ readonly isSeasonalWorker: false;
456
+ readonly maximumQuarterlySuperContributionsBase: false;
457
+ readonly superThresholdAmount: false;
458
+ readonly singleTouchPayroll: false;
459
+ readonly dateOfBirth: false;
460
+ readonly gender: false;
461
+ readonly title: false;
462
+ readonly middleName: false;
463
+ readonly preferredName: false;
464
+ readonly previousSurname: false;
465
+ readonly emailAddress: true;
466
+ readonly homePhone: false;
467
+ readonly mobilePhone: false;
468
+ readonly workPhone: false;
469
+ readonly bankAccount1_AccountName: false;
470
+ readonly bankAccount1_AccountNumber: false;
471
+ readonly bankAccount1_AllocatedPercentage: false;
472
+ readonly bankAccount1_BSB: false;
473
+ readonly bankAccount1_FixedAmount: false;
474
+ readonly bankAccount2_AccountName: false;
475
+ readonly bankAccount2_AccountNumber: false;
476
+ readonly bankAccount2_AllocatedPercentage: false;
477
+ readonly bankAccount2_BSB: false;
478
+ readonly bankAccount2_FixedAmount: false;
479
+ readonly bankAccount3_AccountName: false;
480
+ readonly bankAccount3_AccountNumber: false;
481
+ readonly bankAccount3_AllocatedPercentage: false;
482
+ readonly bankAccount3_BSB: false;
483
+ readonly bankAccount3_FixedAmount: false;
484
+ readonly emergencyContact1_Address: false;
485
+ readonly emergencyContact1_AlternateContactNumber: false;
486
+ readonly emergencyContact1_ContactNumber: false;
487
+ readonly emergencyContact1_Name: false;
488
+ readonly emergencyContact1_Relationship: false;
489
+ readonly emergencyContact2_Address: false;
490
+ readonly emergencyContact2_AlternateContactNumber: false;
491
+ readonly emergencyContact2_ContactNumber: false;
492
+ readonly emergencyContact2_Name: false;
493
+ readonly emergencyContact2_Relationship: false;
494
+ readonly postalStreetAddress: false;
495
+ readonly postalAddressLine2: false;
496
+ readonly postalPostCode: false;
497
+ readonly postalCountry: false;
498
+ readonly postalState: false;
499
+ readonly postalSuburb: false;
500
+ readonly postalAddressIsOverseas: false;
501
+ readonly residentialStreetAddress: false;
502
+ readonly residentialAddressLine2: false;
503
+ readonly residentialPostCode: false;
504
+ readonly residentialCountry: false;
505
+ readonly residentialState: false;
506
+ readonly residentialSuburb: false;
507
+ readonly residentialAddressIsOverseas: false;
508
+ readonly taxFileNumber: false;
509
+ readonly taxCategory: false;
510
+ readonly taxVariation: false;
511
+ readonly claimTaxFreeThreshold: false;
512
+ readonly claimMedicareLevyReduction: false;
513
+ readonly medicareLevyExemption: false;
514
+ readonly medicareLevyReductionDependentCount: false;
515
+ readonly medicareLevyReductionSpouse: false;
516
+ readonly medicareLevySurchargeWithholdingTier: false;
517
+ readonly seniorsTaxOffset: false;
518
+ readonly otherTaxOffset: false;
519
+ readonly stslDebt: false;
520
+ readonly hasWithholdingVariation: false;
521
+ readonly dateTaxFileDeclarationReported: false;
522
+ readonly dateTaxFileDeclarationSigned: false;
523
+ readonly superFund1_AllocatedPercentage: false;
524
+ readonly superFund1_EmployerNominatedFund: false;
525
+ readonly superFund1_FixedAmount: false;
526
+ readonly superFund1_FundName: false;
527
+ readonly superFund1_MemberNumber: false;
528
+ readonly superFund1_ProductCode: false;
529
+ readonly superFund2_AllocatedPercentage: false;
530
+ readonly superFund2_EmployerNominatedFund: false;
531
+ readonly superFund2_FixedAmount: false;
532
+ readonly superFund2_FundName: false;
533
+ readonly superFund2_MemberNumber: false;
534
+ readonly superFund2_ProductCode: false;
535
+ readonly superFund3_AllocatedPercentage: false;
536
+ readonly superFund3_EmployerNominatedFund: false;
537
+ readonly superFund3_FixedAmount: false;
538
+ readonly superFund3_FundName: false;
539
+ readonly superFund3_MemberNumber: false;
540
+ readonly superFund3_ProductCode: false;
541
+ readonly contractorABN: false;
542
+ readonly employingEntityABN: false;
543
+ readonly hasApprovedWorkingHolidayVisa: false;
544
+ readonly workingHolidayVisaCountry: false;
545
+ readonly workingHolidayVisaStartDate: false;
546
+ };
547
+ import type { EntityDef } from '@markwharton/api-core';
548
+ /** Entity registry — maps interface names to field specs and API path segments. */
549
+ export declare const ENTITIES: Record<string, EntityDef>;
375
550
  /** Access tier for method-level authorization */
376
551
  export type AccessTier = 'standard' | 'restricted';
377
552
  /**
378
553
  * Access tier for each data method.
379
554
  *
380
- * Standard: operational data (locations, groups, kiosks, roster shifts, report fields).
381
- * Restricted: employee-level data (employees, standard hours, leave requests, employee reports).
555
+ * Standard: operational data (locations, groups, kiosks, roster shifts).
556
+ * Restricted: employee-level data (employees, standard hours, leave requests).
382
557
  * Utility methods (validate, clear, invalidate) are not included.
383
558
  */
384
559
  export declare const METHOD_TIERS: Record<string, AccessTier>;
package/dist/types.js CHANGED
@@ -5,129 +5,126 @@
5
5
  * Based on the API reference and KeyPay .NET SDK models.
6
6
  */
7
7
  // ============================================================================
8
- // Field Key Constants (whitelists for pickFields)
8
+ // Field Definitions (for pickFields)
9
9
  // ============================================================================
10
- /** Whitelisted fields for EHLeaveRequest */
11
- export const LEAVE_REQUEST_FIELDS = [
12
- 'id', 'employeeId', 'leaveCategoryId', 'employee', 'leaveCategory',
13
- 'fromDate', 'toDate', 'totalHours', 'hoursApplied', 'notes', 'status',
14
- ];
15
- /** Whitelisted fields for EHLocation */
16
- export const LOCATION_FIELDS = [
17
- 'id', 'parentId', 'name', 'externalId', 'source',
18
- 'fullyQualifiedName', 'isGlobal', 'state', 'country',
19
- ];
20
- /** Whitelisted fields for EHKiosk */
21
- export const KIOSK_FIELDS = [
22
- 'id', 'externalId', 'name', 'locationId', 'timeZone', 'ianaTimeZone',
23
- 'allowHigherClassificationSelection', 'isLocationRequired', 'isWorkTypeRequired',
24
- 'restrictLocationsForEmployees', 'allowEmployeeShiftSelection',
25
- 'clockOnWindowMinutes', 'clockOffWindowMinutes',
26
- 'isPhotoRequired', 'canAddEmployees', 'paidBreaksEnabled',
27
- ];
28
- /** Whitelisted fields for EHKioskEmployee */
29
- export const KIOSK_EMPLOYEE_FIELDS = [
30
- 'employeeId', 'firstName', 'surname', 'name', 'status',
31
- 'clockOnTimeUtc', 'breakStartTimeUtc', 'currentShiftId',
32
- 'employeeStartDate', 'employeeGroupIds', 'longShift', 'recordedTimeUtc',
33
- ];
34
- /** Whitelisted fields for EHEmployeeGroup */
35
- export const EMPLOYEE_GROUP_FIELDS = [
36
- 'id', 'name',
37
- ];
38
- /** Whitelisted fields for EHRosterShift */
39
- export const ROSTER_SHIFT_FIELDS = [
40
- 'id', 'employeeId', 'employeeName', 'locationId', 'locationName',
41
- 'workTypeId', 'workTypeName', 'startTime', 'endTime',
42
- 'notes', 'published', 'accepted',
43
- ];
44
- /**
45
- * Operational fields for EHAuEmployee (52 fields)
46
- * Identity, employment structure, pay config, scheduling, leave, AU compliance.
47
- */
48
- export const AU_EMPLOYEE_OPERATIONAL_FIELDS = [
10
+ /** Fields for EHLeaveRequest — set false to exclude from API responses */
11
+ export const LEAVE_REQUEST_FIELDS = {
12
+ id: true, employeeId: true, leaveCategoryId: true, employee: true, leaveCategory: true,
13
+ fromDate: true, toDate: true, totalHours: true, hoursApplied: true, notes: true, status: true,
14
+ };
15
+ /** Fields for EHLocation — set false to exclude from API responses */
16
+ export const LOCATION_FIELDS = {
17
+ id: true, parentId: true, name: true, externalId: true, source: true,
18
+ fullyQualifiedName: true, isGlobal: true, state: true, country: true,
19
+ };
20
+ /** Fields for EHKiosk — set false to exclude from API responses */
21
+ export const KIOSK_FIELDS = {
22
+ id: true, externalId: true, name: true, locationId: true, timeZone: true, ianaTimeZone: true,
23
+ allowHigherClassificationSelection: true, isLocationRequired: true, isWorkTypeRequired: true,
24
+ restrictLocationsForEmployees: true, allowEmployeeShiftSelection: true,
25
+ clockOnWindowMinutes: true, clockOffWindowMinutes: true,
26
+ isPhotoRequired: true, canAddEmployees: true, paidBreaksEnabled: true,
27
+ };
28
+ /** Fields for EHKioskEmployee — set false to exclude from API responses */
29
+ export const KIOSK_EMPLOYEE_FIELDS = {
30
+ employeeId: true, firstName: true, surname: true, name: true, status: true,
31
+ clockOnTimeUtc: true, breakStartTimeUtc: true, currentShiftId: true,
32
+ employeeStartDate: true, employeeGroupIds: true, longShift: true, recordedTimeUtc: true,
33
+ };
34
+ /** Fields for EHEmployeeGroup — set false to exclude from API responses */
35
+ export const EMPLOYEE_GROUP_FIELDS = {
36
+ id: true, name: true,
37
+ };
38
+ /** Fields for EHRosterShift — set false to exclude from API responses */
39
+ export const ROSTER_SHIFT_FIELDS = {
40
+ id: true, employeeId: true, employeeName: true, locationId: true, locationName: true,
41
+ workTypeId: true, workTypeName: true, startTime: true, endTime: true,
42
+ notes: true, published: true, accepted: true,
43
+ };
44
+ /** Fields for EHAuEmployee — set false to exclude from API responses */
45
+ export const AU_EMPLOYEE_FIELDS = {
49
46
  // Identity
50
- 'id', 'externalId', 'firstName', 'surname', 'status',
47
+ id: true, externalId: true, firstName: true, surname: true, status: true,
51
48
  // Dates
52
- 'startDate', 'endDate', 'anniversaryDate', 'dateCreated',
49
+ startDate: true, endDate: true, anniversaryDate: false, dateCreated: false,
53
50
  // Employment
54
- 'employmentType', 'jobTitle', 'employmentAgreement', 'employmentAgreementId',
51
+ employmentType: true, jobTitle: true, employmentAgreement: false, employmentAgreementId: false,
55
52
  // Pay
56
- 'paySchedule', 'payRateTemplate', 'rate', 'rateUnit', 'hoursPerWeek', 'hoursPerDay',
57
- 'primaryPayCategory', 'payConditionRuleSet', 'overrideTemplateRate', 'automaticallyPayEmployee',
53
+ paySchedule: false, payRateTemplate: false, rate: false, rateUnit: false, hoursPerWeek: false, hoursPerDay: false,
54
+ primaryPayCategory: false, payConditionRuleSet: false, overrideTemplateRate: false, automaticallyPayEmployee: false,
58
55
  // Location/org
59
- 'primaryLocation', 'locations', 'tags', 'workTypes', 'reportingDimensionValues',
56
+ primaryLocation: true, locations: false, tags: false, workTypes: false, reportingDimensionValues: false,
60
57
  // Leave
61
- 'leaveAccrualStartDateType', 'leaveTemplate', 'leaveYearStart',
58
+ leaveAccrualStartDateType: false, leaveTemplate: false, leaveYearStart: false,
62
59
  // Flags
63
- 'isEnabledForTimesheets', 'rosteringNotificationChoices', 'paySlipNotificationType', 'terminationReason',
60
+ isEnabledForTimesheets: false, rosteringNotificationChoices: false, paySlipNotificationType: false, terminationReason: false,
64
61
  // AU compliance
65
- 'australianResident', 'awardId', 'businessAwardPackage',
66
- 'automaticallyApplyPublicHolidayNotWorkedEarningsLines',
67
- 'closelyHeldEmployee', 'closelyHeldReporting',
68
- 'disableAutoProgression', 'dvlPaySlipDescription',
69
- 'employingEntityId',
70
- 'includeInPortableLongServiceLeaveReport', 'portableLongServiceLeaveId',
71
- 'isExemptFromFloodLevy', 'isExemptFromPayrollTax', 'isSeasonalWorker',
72
- 'maximumQuarterlySuperContributionsBase', 'superThresholdAmount',
73
- 'singleTouchPayroll',
74
- ];
75
- /**
76
- * PII fields for EHAuEmployee (87 fields)
77
- * Personal data, contact info, bank accounts, addresses, tax, super, emergency contacts.
78
- */
79
- export const AU_EMPLOYEE_PII_FIELDS = [
62
+ australianResident: false, awardId: false, businessAwardPackage: false,
63
+ automaticallyApplyPublicHolidayNotWorkedEarningsLines: false,
64
+ closelyHeldEmployee: false, closelyHeldReporting: false,
65
+ disableAutoProgression: false, dvlPaySlipDescription: false,
66
+ employingEntityId: false,
67
+ includeInPortableLongServiceLeaveReport: false, portableLongServiceLeaveId: false,
68
+ isExemptFromFloodLevy: false, isExemptFromPayrollTax: false, isSeasonalWorker: false,
69
+ maximumQuarterlySuperContributionsBase: false, superThresholdAmount: false,
70
+ singleTouchPayroll: false,
80
71
  // Personal
81
- 'dateOfBirth', 'gender', 'title', 'middleName', 'preferredName', 'previousSurname',
72
+ dateOfBirth: false, gender: false, title: false, middleName: false, preferredName: false, previousSurname: false,
82
73
  // Contact
83
- 'emailAddress', 'homePhone', 'mobilePhone', 'workPhone',
74
+ emailAddress: true, homePhone: false, mobilePhone: false, workPhone: false,
84
75
  // Bank accounts
85
- 'bankAccount1_AccountName', 'bankAccount1_AccountNumber',
86
- 'bankAccount1_AllocatedPercentage', 'bankAccount1_BSB', 'bankAccount1_FixedAmount',
87
- 'bankAccount2_AccountName', 'bankAccount2_AccountNumber',
88
- 'bankAccount2_AllocatedPercentage', 'bankAccount2_BSB', 'bankAccount2_FixedAmount',
89
- 'bankAccount3_AccountName', 'bankAccount3_AccountNumber',
90
- 'bankAccount3_AllocatedPercentage', 'bankAccount3_BSB', 'bankAccount3_FixedAmount',
76
+ bankAccount1_AccountName: false, bankAccount1_AccountNumber: false,
77
+ bankAccount1_AllocatedPercentage: false, bankAccount1_BSB: false, bankAccount1_FixedAmount: false,
78
+ bankAccount2_AccountName: false, bankAccount2_AccountNumber: false,
79
+ bankAccount2_AllocatedPercentage: false, bankAccount2_BSB: false, bankAccount2_FixedAmount: false,
80
+ bankAccount3_AccountName: false, bankAccount3_AccountNumber: false,
81
+ bankAccount3_AllocatedPercentage: false, bankAccount3_BSB: false, bankAccount3_FixedAmount: false,
91
82
  // Emergency contacts
92
- 'emergencyContact1_Address', 'emergencyContact1_AlternateContactNumber',
93
- 'emergencyContact1_ContactNumber', 'emergencyContact1_Name', 'emergencyContact1_Relationship',
94
- 'emergencyContact2_Address', 'emergencyContact2_AlternateContactNumber',
95
- 'emergencyContact2_ContactNumber', 'emergencyContact2_Name', 'emergencyContact2_Relationship',
83
+ emergencyContact1_Address: false, emergencyContact1_AlternateContactNumber: false,
84
+ emergencyContact1_ContactNumber: false, emergencyContact1_Name: false, emergencyContact1_Relationship: false,
85
+ emergencyContact2_Address: false, emergencyContact2_AlternateContactNumber: false,
86
+ emergencyContact2_ContactNumber: false, emergencyContact2_Name: false, emergencyContact2_Relationship: false,
96
87
  // Postal address
97
- 'postalStreetAddress', 'postalAddressLine2', 'postalPostCode', 'postalCountry',
98
- 'postalState', 'postalSuburb', 'postalAddressIsOverseas',
88
+ postalStreetAddress: false, postalAddressLine2: false, postalPostCode: false, postalCountry: false,
89
+ postalState: false, postalSuburb: false, postalAddressIsOverseas: false,
99
90
  // Residential address
100
- 'residentialStreetAddress', 'residentialAddressLine2', 'residentialPostCode', 'residentialCountry',
101
- 'residentialState', 'residentialSuburb', 'residentialAddressIsOverseas',
91
+ residentialStreetAddress: false, residentialAddressLine2: false, residentialPostCode: false, residentialCountry: false,
92
+ residentialState: false, residentialSuburb: false, residentialAddressIsOverseas: false,
102
93
  // Tax
103
- 'taxFileNumber', 'taxCategory', 'taxVariation',
104
- 'claimTaxFreeThreshold', 'claimMedicareLevyReduction',
105
- 'medicareLevyExemption', 'medicareLevyReductionDependentCount',
106
- 'medicareLevyReductionSpouse', 'medicareLevySurchargeWithholdingTier',
107
- 'seniorsTaxOffset', 'otherTaxOffset', 'stslDebt',
108
- 'hasWithholdingVariation', 'dateTaxFileDeclarationReported', 'dateTaxFileDeclarationSigned',
94
+ taxFileNumber: false, taxCategory: false, taxVariation: false,
95
+ claimTaxFreeThreshold: false, claimMedicareLevyReduction: false,
96
+ medicareLevyExemption: false, medicareLevyReductionDependentCount: false,
97
+ medicareLevyReductionSpouse: false, medicareLevySurchargeWithholdingTier: false,
98
+ seniorsTaxOffset: false, otherTaxOffset: false, stslDebt: false,
99
+ hasWithholdingVariation: false, dateTaxFileDeclarationReported: false, dateTaxFileDeclarationSigned: false,
109
100
  // Super funds
110
- 'superFund1_AllocatedPercentage', 'superFund1_EmployerNominatedFund',
111
- 'superFund1_FixedAmount', 'superFund1_FundName', 'superFund1_MemberNumber', 'superFund1_ProductCode',
112
- 'superFund2_AllocatedPercentage', 'superFund2_EmployerNominatedFund',
113
- 'superFund2_FixedAmount', 'superFund2_FundName', 'superFund2_MemberNumber', 'superFund2_ProductCode',
114
- 'superFund3_AllocatedPercentage', 'superFund3_EmployerNominatedFund',
115
- 'superFund3_FixedAmount', 'superFund3_FundName', 'superFund3_MemberNumber', 'superFund3_ProductCode',
101
+ superFund1_AllocatedPercentage: false, superFund1_EmployerNominatedFund: false,
102
+ superFund1_FixedAmount: false, superFund1_FundName: false, superFund1_MemberNumber: false, superFund1_ProductCode: false,
103
+ superFund2_AllocatedPercentage: false, superFund2_EmployerNominatedFund: false,
104
+ superFund2_FixedAmount: false, superFund2_FundName: false, superFund2_MemberNumber: false, superFund2_ProductCode: false,
105
+ superFund3_AllocatedPercentage: false, superFund3_EmployerNominatedFund: false,
106
+ superFund3_FixedAmount: false, superFund3_FundName: false, superFund3_MemberNumber: false, superFund3_ProductCode: false,
116
107
  // ABNs
117
- 'contractorABN', 'employingEntityABN',
108
+ contractorABN: false, employingEntityABN: false,
118
109
  // Visa
119
- 'hasApprovedWorkingHolidayVisa', 'workingHolidayVisaCountry', 'workingHolidayVisaStartDate',
120
- ];
121
- /** All whitelisted fields for EHAuEmployee (operational + PII) */
122
- export const AU_EMPLOYEE_FIELDS = [
123
- ...AU_EMPLOYEE_OPERATIONAL_FIELDS,
124
- ...AU_EMPLOYEE_PII_FIELDS,
125
- ];
110
+ hasApprovedWorkingHolidayVisa: false, workingHolidayVisaCountry: false, workingHolidayVisaStartDate: false,
111
+ };
112
+ /** Entity registry maps interface names to field specs and API path segments. */
113
+ export const ENTITIES = {
114
+ EHAuEmployee: { fields: AU_EMPLOYEE_FIELDS, path: 'employee/unstructured' },
115
+ EHLeaveRequest: { fields: LEAVE_REQUEST_FIELDS, path: 'leaverequest' },
116
+ EHEmployeeLeaveRequest: { fields: LEAVE_REQUEST_FIELDS, path: 'employee/{employeeId}/leaverequest' },
117
+ EHLocation: { fields: LOCATION_FIELDS, path: 'location' },
118
+ EHRosterShift: { fields: ROSTER_SHIFT_FIELDS, path: 'rostershift' },
119
+ EHKiosk: { fields: KIOSK_FIELDS, path: 'kiosk' },
120
+ EHKioskEmployee: { fields: KIOSK_EMPLOYEE_FIELDS, path: 'kiosk/{kioskId}/staff' },
121
+ EHEmployeeGroup: { fields: EMPLOYEE_GROUP_FIELDS, path: 'employeegroup' },
122
+ };
126
123
  /**
127
124
  * Access tier for each data method.
128
125
  *
129
- * Standard: operational data (locations, groups, kiosks, roster shifts, report fields).
130
- * Restricted: employee-level data (employees, standard hours, leave requests, employee reports).
126
+ * Standard: operational data (locations, groups, kiosks, roster shifts).
127
+ * Restricted: employee-level data (employees, standard hours, leave requests).
131
128
  * Utility methods (validate, clear, invalidate) are not included.
132
129
  */
133
130
  export const METHOD_TIERS = {
@@ -136,10 +133,9 @@ export const METHOD_TIERS = {
136
133
  getKiosks: 'standard',
137
134
  getKioskStaff: 'standard',
138
135
  getRosterShifts: 'standard',
139
- getReportFields: 'standard',
140
136
  getEmployees: 'restricted',
141
137
  getLeaveRequests: 'restricted',
138
+ getEmployeeLeaveRequests: 'restricted',
142
139
  getEmployee: 'restricted',
143
140
  getStandardHours: 'restricted',
144
- getEmployeeDetailsReport: 'restricted',
145
141
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@markwharton/eh-payroll",
3
- "version": "2.4.0",
3
+ "version": "2.5.1",
4
4
  "description": "Employment Hero Payroll API client",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",