diff --git a/README.md b/README.md index 5b7c9e8..159377b 100644 --- a/README.md +++ b/README.md @@ -86,10 +86,15 @@ In order to use this library you need to have access to an Oracle Field Service ### Core: Resource Management +`getResource(resourceId, params?)`: Get a single resource by ID + +- `params.expand` (array): Include sub-entities like inventories, workZones, workSkills +- `params.fields` (array): Specify which resource fields to return + `getResources(params?)`: Get existing resources with optional filtering parameters - `params.canBeTeamHolder` (boolean): Filter resources that can be team holders -- `params.canParticipateInTeam` (boolean): Filter resources that can participate in teams +- `params.canParticipateInTeam` (boolean): Filter resources that can participate in teams - `params.expand` (array): Include sub-entities like inventories, workZones, workSkills - `params.fields` (array): Specify which resource fields to return - `params.limit` (number): Number of items to return (1-100, default 100) @@ -129,6 +134,7 @@ Please see the `docs/` directory for documentation and a simple example | 1.6 | Added `getUsers`, `getUserDetails`, `getAllUsers` | | 1.8 | Added `getProperties`, `getPropertyDetails`, `updateProperty` `createReplaceProperty` | | 1.23 | Added `getLinkedActivities`, `getActivityLinkType` methods | +| 1.25 | Added `getResource` method for single resource retrieval | ## Contributing diff --git a/package-lock.json b/package-lock.json index 9dede61..70a7889 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@ofs-users/proxy", - "version": "1.24.0", + "version": "1.27.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@ofs-users/proxy", - "version": "1.24.0", + "version": "1.27.0", "license": "UPL-1.0", "dependencies": { "@ofs-users/proxy": "^1.9.0", diff --git a/package.json b/package.json index a71cb93..8eed471 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ ], "name": "@ofs-users/proxy", "type": "module", - "version": "1.24.0", + "version": "1.27.0", "description": "A Javascript proxy to access Oracle Field Service via REST API", "main": "dist/ofs.es.js", "module": "dist/ofs.es.js", diff --git a/src/OFS.ts b/src/OFS.ts index 141a983..b018e8a 100644 --- a/src/OFS.ts +++ b/src/OFS.ts @@ -18,7 +18,9 @@ import { OFSSearchForActivitiesParams, OFSBulkUpdateRequest, OFSGetResourcesParams, + OFSGetResourceParams, OFSResourceResponse, + OFSSingleResourceResponse, OFSResourceRoutesResponse, OFSGetLastKnownPositionsParams, OFSLastKnownPositionsResponse, @@ -731,6 +733,29 @@ export class OFS { return allResults; } + /** + * Retrieves a single resource by ID from the OFS API. + * @param resourceId The ID of the resource to retrieve + * @param params Optional parameters for expanding or filtering fields + * @returns The resource details + */ + async getResource( + resourceId: string, + params: OFSGetResourceParams = {} + ): Promise { + const partialURL = `/rest/ofscCore/v1/resources/${resourceId}`; + const queryParams: any = {}; + + if (params.expand && params.expand.length > 0) { + queryParams.expand = params.expand.join(','); + } + if (params.fields && params.fields.length > 0) { + queryParams.fields = params.fields.join(','); + } + + return this._get(partialURL, Object.keys(queryParams).length > 0 ? queryParams : undefined); + } + async getResourceRoutes( resourceId: string, date: string, diff --git a/src/model.ts b/src/model.ts index 6c2e337..cb5e358 100644 --- a/src/model.ts +++ b/src/model.ts @@ -350,6 +350,20 @@ export class OFSResourceResponse extends OFSResponse { }; } +export interface OFSGetResourceParams { + expand?: string[]; + fields?: string[]; +} + +export class OFSSingleResourceResponse extends OFSResponse { + data: OFSResource = { + resourceId: '', + name: '', + status: '', + resourceType: '', + }; +} + export interface OFSGetResourceRoutesParams { resourceId: string; date: string; diff --git a/test/general/core.resources.test.ts b/test/general/core.resources.test.ts index c8ab8db..a2bb71e 100644 --- a/test/general/core.resources.test.ts +++ b/test/general/core.resources.test.ts @@ -20,6 +20,79 @@ beforeAll(() => { } }); +// Tests for getResource method +test("Get Resource with valid ID", async () => { + var resourceId = "33035"; + var result = await myProxy.getResource(resourceId); + + expect(result).toBeDefined(); + expect(result.status).toBeDefined(); + expect(result.data).toBeDefined(); + + if (result.status === 200 && result.data) { + expect(result.data.resourceId).toBe(resourceId); + expect(result.data.name).toBeDefined(); + expect(result.data.status).toBeDefined(); + expect(result.data.resourceType).toBeDefined(); + } +}); + +test("Get Resource with invalid ID", async () => { + var resourceId = "INVALID_RESOURCE_ID_12345"; + var result = await myProxy.getResource(resourceId); + + expect(result).toBeDefined(); + expect(result.status).toBeDefined(); + + // Expecting 404 for non-existent resource + expect(result.status).toBeGreaterThanOrEqual(400); +}); + +test("Get Resource with fields parameter", async () => { + var resourceId = "33035"; + var fields = ["resourceId", "name", "status"]; + var result = await myProxy.getResource(resourceId, { fields }); + + expect(result).toBeDefined(); + expect(result.status).toBeDefined(); + expect(result.data).toBeDefined(); + + if (result.status === 200 && result.data) { + expect(result.data.resourceId).toBe(resourceId); + } +}); + +test("Get Resource with expand parameter", async () => { + var resourceId = "33035"; + var expand = ["workSkills", "workZones"]; + var result = await myProxy.getResource(resourceId, { expand }); + + expect(result).toBeDefined(); + expect(result.status).toBeDefined(); + expect(result.data).toBeDefined(); + + if (result.status === 200 && result.data) { + expect(result.data.resourceId).toBe(resourceId); + } +}); + +test("Get Resource response structure validation", async () => { + var resourceId = "33035"; + var result = await myProxy.getResource(resourceId); + + expect(result).toBeDefined(); + expect(result.status).toBeDefined(); + expect(typeof result.status).toBe('number'); + expect(result.data).toBeDefined(); + + if (result.status === 200) { + expect(result.data.resourceId).toBeDefined(); + expect(typeof result.data.resourceId).toBe('string'); + expect(result.data.name).toBeDefined(); + expect(typeof result.data.name).toBe('string'); + } +}); + test("Get Resource Routes with default activity fields", async () => { var resourceId = "100000471803411"; var date = "2025-06-23";