pha-hermes 1.0.0

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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hermes.esm.js","sources":["../src/api/auth/auth.ts","../src/api/timesheet/timesheetClient.ts","../src/api/practitioner/practitionerClient.ts","../src/api/apiClient.ts"],"sourcesContent":["import axios, { AxiosInstance } from 'axios'\r\nimport FormData from 'form-data'\r\n\r\nexport class SFAuthenticator {\r\n axiosTokenInstance: AxiosInstance = axios.create()\r\n authenticatedAxiosInstance: AxiosInstance\r\n token: string | undefined = undefined\r\n private refreshToken: string | undefined = undefined\r\n\r\n constructor(authenticatedAxiosInstance: AxiosInstance, baseUrl?: string) {\r\n this.axiosTokenInstance.defaults.baseURL =\r\n baseUrl ?? 'https://do0000000d247eaa--phealth.sandbox.my.salesforce.com'\r\n this.authenticatedAxiosInstance = authenticatedAxiosInstance\r\n }\r\n\r\n async initializeAuth(clientId: string, clientSecret: string) {\r\n const token = await this.postToken(clientId, clientSecret)\r\n this.authenticatedAxiosInstance.defaults.headers.common['Authorization'] = `Bearer ${token}`\r\n }\r\n\r\n async postToken(clientId?: string, clientSecret?: string): Promise<string> {\r\n const tokenFormRequestBody = new FormData()\r\n if (this.refreshToken) {\r\n tokenFormRequestBody.append('refresh_token', this.refreshToken)\r\n tokenFormRequestBody.append('grant_type', 'refresh_token')\r\n } else if (clientId && clientSecret) {\r\n tokenFormRequestBody.append('client_id', clientId)\r\n tokenFormRequestBody.append('client_secret', clientSecret)\r\n tokenFormRequestBody.append('grant_type', 'client_credentials')\r\n } else {\r\n throw new Error(\r\n 'Authentication failed, either the RefreshToken, or ClientId and ClientSecret need to be provided'\r\n )\r\n }\r\n\r\n const response = await this.axiosTokenInstance.post(\r\n '/services/oauth2/token',\r\n tokenFormRequestBody,\r\n {\r\n headers: tokenFormRequestBody.getHeaders()\r\n }\r\n )\r\n\r\n this.token = response?.data?.['access_token']\r\n if (!this.token) throw new Error('Authentication failed, could not get the access token')\r\n return this.token\r\n }\r\n}\r\n","import { AxiosInstance } from 'axios'\r\nimport { TimesheetDayEntry } from '../../models'\r\nimport { SF_API_VERSION } from '../apiClient'\r\n\r\nexport class SFTimesheetClient {\r\n private axiosInstance: AxiosInstance\r\n\r\n constructor(axiosInstance: AxiosInstance) {\r\n this.axiosInstance = axiosInstance\r\n }\r\n\r\n async updateTimesheetHour(timesheetHourId: string, timesheet: TimesheetDayEntry) {\r\n try {\r\n const url = `/services/data/${SF_API_VERSION}/sobjects/TimeSheetHour__c/${timesheetHourId}`\r\n const response = await this.axiosInstance.patch(url, {\r\n Callback__c: timesheet.callbackHours,\r\n HoursEBAdjusted__c: timesheet.regularHours,\r\n Misc__c: timesheet.miscHours,\r\n OT1__c: timesheet.overtime1Hours,\r\n OT2__c: timesheet.overtime2Hours,\r\n OnCall__c: timesheet.onCallHours,\r\n Misc1__c: timesheet.misc1HoursA,\r\n Misc_1_Hours__c: timesheet.misc1HoursB,\r\n Misc_2_Hours__c: timesheet.misc2Hours,\r\n Misc_3_Hours__c: timesheet.misc3Hours,\r\n Misc_4_Hours__c: timesheet.misc4Hours,\r\n Stat1__c: timesheet.stat1Hours,\r\n Stat2__c: timesheet.stat2Hours,\r\n In_Charge__c: timesheet.inChargeHours,\r\n Shift_Travel_Stipend__c: timesheet.shiftTravelPerDiemHours\r\n })\r\n\r\n if (![200, 204, 304].includes(response.status))\r\n throw new Error(`got error status code ${response.status}`)\r\n } catch (error) {\r\n console.error('Error Updating Timesheet Hour: ', error.message)\r\n }\r\n }\r\n\r\n async getTimesheetId(workorderId: string): Promise<string> {\r\n // First we find the correct timesheet id\r\n const url = `/services/data/${SF_API_VERSION}/query`\r\n const query = `SELECT Id FROM Timesheet__c WHERE WorkOrder__c = '${workorderId}' LIMIT 1`\r\n const {\r\n data: { records }\r\n } = await this.axiosInstance.get(url, {\r\n params: { q: query }\r\n })\r\n return records[0].Id\r\n }\r\n\r\n async getTimesheetHoursIds(workorderId: string): Promise<string[]> {\r\n const timesheetId = await this.getTimesheetId(workorderId)\r\n // First we find the correct timesheet hours id\r\n const url = `/services/data/${SF_API_VERSION}/query`\r\n const query = `SELECT Id FROM TimesheetHour__c WHERE Timesheet__c = '${timesheetId}'`\r\n const {\r\n data: { records }\r\n } = await this.axiosInstance.get(url, {\r\n params: { q: query }\r\n })\r\n return records.map(({ Id }) => Id)\r\n }\r\n\r\n async getTimesheetHours(workorderId: string): Promise<TimesheetDayEntry[]> {\r\n const timesheetHourIds = await this.getTimesheetHoursIds(workorderId)\r\n return Promise.all(\r\n timesheetHourIds.map(async id =>\r\n this.axiosInstance\r\n .get(`/services/data/${SF_API_VERSION}/sobjects/TimeSheetHour__c/${id}`)\r\n .then(res => res.data)\r\n .then(toTimesheetDayEntry)\r\n )\r\n )\r\n }\r\n}\r\n\r\nfunction toTimesheetDayEntry(raw: any): TimesheetDayEntry {\r\n return {\r\n callbackHours: raw.Callback__c,\r\n regularHours: raw.HoursEBAdjusted__c,\r\n miscHours: raw.Misc__c,\r\n overtime1Hours: raw.OT1__c,\r\n overtime2Hours: raw.OT2__c,\r\n onCallHours: raw.OnCall__c,\r\n misc1HoursA: raw.Misc1__c,\r\n misc1HoursB: raw.Misc_1_Hours__c,\r\n misc2Hours: raw.Misc_2_Hours__c,\r\n misc3Hours: raw.Misc_3_Hours__c,\r\n misc4Hours: raw.Misc_4_Hours__c,\r\n stat1Hours: raw.Stat1__c,\r\n stat2Hours: raw.Stat2__c,\r\n inChargeHours: raw.In_Charge__c,\r\n shiftTravelPerDiemHours: raw.Shift_Travel_Stipend__c\r\n }\r\n}\r\n","import { AxiosInstance } from 'axios'\nimport { Practitioner } from '../../models/practitioner'\nimport { SF_API_VERSION } from '../apiClient'\n\nexport class SFPractitionerClient {\n private axiosInstance: AxiosInstance\n\n constructor(axiosInstance: AxiosInstance) {\n this.axiosInstance = axiosInstance\n }\n\n async fetchPractitioners(): Promise<Practitioner[]> {\n try {\n const url = `/services/data/${SF_API_VERSION}/query`\n const query = `\n SELECT Id, FirstName__c, LastName__c, Email__c, StaffID__c\n FROM Personnel__c\n WHERE Status__c = 'Active'\n `\n const {\n data: { records }\n } = await this.axiosInstance.get(url, {\n params: { q: query }\n })\n\n return records.map(toPractitioner)\n } catch (error) {\n console.error('Error fetching practitioners: ', error.message)\n throw error\n }\n }\n}\n\nfunction toPractitioner(raw: any): Practitioner {\n return {\n id: raw.Id,\n firstName: raw.FirstName__c,\n lastName: raw.LastName__c,\n email: raw.Email__c,\n staffId: raw.StaffID__c\n }\n}\n","import axios, { AxiosInstance } from 'axios'\nimport { SFAuthenticator } from './auth/auth'\nimport { SFTimesheetClient } from './timesheet/timesheetClient'\nimport { SFPractitionerClient } from './practitioner/practitionerClient'\nimport { Role, Workorder } from '../models'\nexport const SF_API_VERSION: string = 'v57.0'\n\nexport class SFApiClient {\n private instance: SFApiClient | undefined = undefined\n private axiosInstance: AxiosInstance = axios.create()\n private authenticator: SFAuthenticator\n private baseUrl: string\n timesheetClient: SFTimesheetClient\n practitionerClient: SFPractitionerClient\n\n constructor(baseUrl?: string) {\n this.baseUrl = baseUrl\n this.axiosInstance.defaults.baseURL =\n baseUrl ?? 'https://do0000000d247eaa--phealth.sandbox.my.salesforce.com'\n this.authenticator = new SFAuthenticator(this.axiosInstance, this.baseUrl)\n this.timesheetClient = new SFTimesheetClient(this.axiosInstance)\n this.practitionerClient = new SFPractitionerClient(this.axiosInstance)\n }\n\n async init(sfClientId: string, sfClientSecret: string) {\n // creates authenticator and adds token to axios instance\n await this.authenticator.initializeAuth(sfClientId, sfClientSecret)\n }\n\n setInstance(instance: SFApiClient) {\n this.instance = instance\n }\n getInstance(): SFApiClient {\n return this.instance\n }\n\n async fetchWorkOrders(assignedStaffId?: string): Promise<Workorder[]> {\n try {\n const url = `/services/data/${SF_API_VERSION}/query`\n const query = assignedStaffId\n ? `SELECT Id, HospitalID__c, HospitalName__c, ProfessionalDesignation__c FROM WorkOrder__c WHERE Personnel__c = '${assignedStaffId}'`\n : `SELECT Id, HospitalID__c, HospitalName__c, ProfessionalDesignation__c FROM WorkOrder__c`\n return await this.axiosInstance\n .get(url, {\n params: { q: query }\n })\n .then(({ data: { records } }) =>\n records.map(\n (record): Workorder => ({\n id: record.Id,\n establishmentId: record.HospitalID__c,\n establishmentName: record.HospitalName__c,\n role: record.ProfessionalDesignation__c\n })\n )\n )\n } catch (error) {\n console.error('Error fetching work orders: ', error.message)\n throw error\n }\n }\n\n async fetchRoles(): Promise<Role[]> {\n try {\n const url = `/services/data/${SF_API_VERSION}/query`\n const query = `SELECT Label, Value FROM PicklistValueInfo \\\n WHERE EntityParticle.EntityDefinition.QualifiedApiName = 'WorkOrder__c'\\\n AND EntityParticle.QualifiedApiName = 'ProfessionalDesignation__c' \\\n AND isActive = true`\n return this.axiosInstance\n .get(url, {\n params: { q: query }\n })\n .then(({ data: { records } }) =>\n records.map((record): Role => ({ label: record.Label, value: record.Value }))\n )\n } catch (error) {\n console.error('Error fetching roles: ', error.message)\n throw error\n }\n }\n}\n"],"names":["SFAuthenticator","authenticatedAxiosInstance","baseUrl","axios","create","undefined","axiosTokenInstance","defaults","baseURL","_proto","prototype","initializeAuth","_initializeAuth","_asyncToGenerator","_regeneratorRuntime","mark","_callee","clientId","clientSecret","token","wrap","_callee$","_context","prev","next","postToken","sent","headers","common","stop","_x","_x2","apply","arguments","_postToken","_callee2","_response$data","tokenFormRequestBody","response","_callee2$","_context2","FormData","refreshToken","append","Error","post","getHeaders","data","abrupt","_x3","_x4","SFTimesheetClient","axiosInstance","updateTimesheetHour","_updateTimesheetHour","timesheetHourId","timesheet","url","SF_API_VERSION","patch","Callback__c","callbackHours","HoursEBAdjusted__c","regularHours","Misc__c","miscHours","OT1__c","overtime1Hours","OT2__c","overtime2Hours","OnCall__c","onCallHours","Misc1__c","misc1HoursA","Misc_1_Hours__c","misc1HoursB","Misc_2_Hours__c","misc2Hours","Misc_3_Hours__c","misc3Hours","Misc_4_Hours__c","misc4Hours","Stat1__c","stat1Hours","Stat2__c","stat2Hours","In_Charge__c","inChargeHours","Shift_Travel_Stipend__c","shiftTravelPerDiemHours","includes","status","t0","console","error","message","getTimesheetId","_getTimesheetId","workorderId","query","_yield$this$axiosInst","records","get","params","q","Id","getTimesheetHoursIds","_getTimesheetHoursIds","_callee3","timesheetId","_yield$this$axiosInst2","_callee3$","_context3","map","_ref","getTimesheetHours","_getTimesheetHours","_callee5","_this","timesheetHourIds","_callee5$","_context5","Promise","all","_ref2","_callee4","id","_callee4$","_context4","then","res","toTimesheetDayEntry","_x6","_x5","raw","SFPractitionerClient","fetchPractitioners","_fetchPractitioners","toPractitioner","firstName","FirstName__c","lastName","LastName__c","email","Email__c","staffId","StaffID__c","SFApiClient","authenticator","timesheetClient","practitionerClient","init","_init","sfClientId","sfClientSecret","setInstance","instance","getInstance","fetchWorkOrders","_fetchWorkOrders","assignedStaffId","record","establishmentId","HospitalID__c","establishmentName","HospitalName__c","role","ProfessionalDesignation__c","fetchRoles","_fetchRoles","label","Label","value","Value"],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export * from './api/apiClient';
2
+ export * from './api/timesheet/timesheetClient';
3
+ export * from './api/auth/auth';
package/dist/index.js ADDED
@@ -0,0 +1,8 @@
1
+
2
+ 'use strict'
3
+
4
+ if (process.env.NODE_ENV === 'production') {
5
+ module.exports = require('./hermes.cjs.production.min.js')
6
+ } else {
7
+ module.exports = require('./hermes.cjs.development.js')
8
+ }
@@ -0,0 +1,12 @@
1
+ export interface Role {
2
+ label: string;
3
+ value: string;
4
+ }
5
+ export interface Workorder {
6
+ id: string;
7
+ establishmentName: string;
8
+ establishmentId: string;
9
+ role: string;
10
+ }
11
+ export * from './timesheet';
12
+ export * from './practitioner';
@@ -0,0 +1,7 @@
1
+ export interface Practitioner {
2
+ id: string;
3
+ firstName: string;
4
+ lastName: string;
5
+ email: string;
6
+ staffId: string;
7
+ }
@@ -0,0 +1,17 @@
1
+ export interface TimesheetDayEntry {
2
+ callbackHours?: number;
3
+ regularHours?: number;
4
+ miscHours?: number;
5
+ overtime1Hours?: number;
6
+ overtime2Hours?: number;
7
+ onCallHours?: number;
8
+ misc1HoursA?: number;
9
+ misc1HoursB?: number;
10
+ misc2Hours?: number;
11
+ misc3Hours?: number;
12
+ misc4Hours?: number;
13
+ stat1Hours?: number;
14
+ stat2Hours?: number;
15
+ inChargeHours?: number;
16
+ shiftTravelPerDiemHours?: number;
17
+ }
package/package.json ADDED
@@ -0,0 +1,31 @@
1
+ {
2
+ "name": "pha-hermes",
3
+ "version": "1.0.0",
4
+ "main": "dist/index.js",
5
+ "typings": "dist/index.d.ts",
6
+ "files": [
7
+ "dist",
8
+ "src"
9
+ ],
10
+ "engines": {
11
+ "node": ">=10",
12
+ "npm": ">=6.14.13"
13
+ },
14
+ "type": "module",
15
+ "module": "dist/hermes.esm.js",
16
+ "scripts": {
17
+ "build": "tsdx build",
18
+ "link:watch": "npm link && tsdx watch"
19
+ },
20
+ "devDependencies": {
21
+ "@types/node": "^22.9.0",
22
+ "prettier": "^3.3.3",
23
+ "tsdx": "^0.14.1",
24
+ "tslib": "^2.8.1",
25
+ "typescript": "^5.0.0"
26
+ },
27
+ "dependencies": {
28
+ "axios": "^1.7.9",
29
+ "form-data": "^4.0.1"
30
+ }
31
+ }
@@ -0,0 +1,82 @@
1
+ import axios, { AxiosInstance } from 'axios'
2
+ import { SFAuthenticator } from './auth/auth'
3
+ import { SFTimesheetClient } from './timesheet/timesheetClient'
4
+ import { SFPractitionerClient } from './practitioner/practitionerClient'
5
+ import { Role, Workorder } from '../models'
6
+ export const SF_API_VERSION: string = 'v57.0'
7
+
8
+ export class SFApiClient {
9
+ private instance: SFApiClient | undefined = undefined
10
+ private axiosInstance: AxiosInstance = axios.create()
11
+ private authenticator: SFAuthenticator
12
+ private baseUrl: string
13
+ timesheetClient: SFTimesheetClient
14
+ practitionerClient: SFPractitionerClient
15
+
16
+ constructor(baseUrl?: string) {
17
+ this.baseUrl = baseUrl
18
+ this.axiosInstance.defaults.baseURL =
19
+ baseUrl ?? 'https://do0000000d247eaa--phealth.sandbox.my.salesforce.com'
20
+ this.authenticator = new SFAuthenticator(this.axiosInstance, this.baseUrl)
21
+ this.timesheetClient = new SFTimesheetClient(this.axiosInstance)
22
+ this.practitionerClient = new SFPractitionerClient(this.axiosInstance)
23
+ }
24
+
25
+ async init(sfClientId: string, sfClientSecret: string) {
26
+ // creates authenticator and adds token to axios instance
27
+ await this.authenticator.initializeAuth(sfClientId, sfClientSecret)
28
+ }
29
+
30
+ setInstance(instance: SFApiClient) {
31
+ this.instance = instance
32
+ }
33
+ getInstance(): SFApiClient {
34
+ return this.instance
35
+ }
36
+
37
+ async fetchWorkOrders(assignedStaffId?: string): Promise<Workorder[]> {
38
+ try {
39
+ const url = `/services/data/${SF_API_VERSION}/query`
40
+ const query = assignedStaffId
41
+ ? `SELECT Id, HospitalID__c, HospitalName__c, ProfessionalDesignation__c FROM WorkOrder__c WHERE Personnel__c = '${assignedStaffId}'`
42
+ : `SELECT Id, HospitalID__c, HospitalName__c, ProfessionalDesignation__c FROM WorkOrder__c`
43
+ return await this.axiosInstance
44
+ .get(url, {
45
+ params: { q: query }
46
+ })
47
+ .then(({ data: { records } }) =>
48
+ records.map(
49
+ (record): Workorder => ({
50
+ id: record.Id,
51
+ establishmentId: record.HospitalID__c,
52
+ establishmentName: record.HospitalName__c,
53
+ role: record.ProfessionalDesignation__c
54
+ })
55
+ )
56
+ )
57
+ } catch (error) {
58
+ console.error('Error fetching work orders: ', error.message)
59
+ throw error
60
+ }
61
+ }
62
+
63
+ async fetchRoles(): Promise<Role[]> {
64
+ try {
65
+ const url = `/services/data/${SF_API_VERSION}/query`
66
+ const query = `SELECT Label, Value FROM PicklistValueInfo \
67
+ WHERE EntityParticle.EntityDefinition.QualifiedApiName = 'WorkOrder__c'\
68
+ AND EntityParticle.QualifiedApiName = 'ProfessionalDesignation__c' \
69
+ AND isActive = true`
70
+ return this.axiosInstance
71
+ .get(url, {
72
+ params: { q: query }
73
+ })
74
+ .then(({ data: { records } }) =>
75
+ records.map((record): Role => ({ label: record.Label, value: record.Value }))
76
+ )
77
+ } catch (error) {
78
+ console.error('Error fetching roles: ', error.message)
79
+ throw error
80
+ }
81
+ }
82
+ }
@@ -0,0 +1,48 @@
1
+ import axios, { AxiosInstance } from 'axios'
2
+ import FormData from 'form-data'
3
+
4
+ export class SFAuthenticator {
5
+ axiosTokenInstance: AxiosInstance = axios.create()
6
+ authenticatedAxiosInstance: AxiosInstance
7
+ token: string | undefined = undefined
8
+ private refreshToken: string | undefined = undefined
9
+
10
+ constructor(authenticatedAxiosInstance: AxiosInstance, baseUrl?: string) {
11
+ this.axiosTokenInstance.defaults.baseURL =
12
+ baseUrl ?? 'https://do0000000d247eaa--phealth.sandbox.my.salesforce.com'
13
+ this.authenticatedAxiosInstance = authenticatedAxiosInstance
14
+ }
15
+
16
+ async initializeAuth(clientId: string, clientSecret: string) {
17
+ const token = await this.postToken(clientId, clientSecret)
18
+ this.authenticatedAxiosInstance.defaults.headers.common['Authorization'] = `Bearer ${token}`
19
+ }
20
+
21
+ async postToken(clientId?: string, clientSecret?: string): Promise<string> {
22
+ const tokenFormRequestBody = new FormData()
23
+ if (this.refreshToken) {
24
+ tokenFormRequestBody.append('refresh_token', this.refreshToken)
25
+ tokenFormRequestBody.append('grant_type', 'refresh_token')
26
+ } else if (clientId && clientSecret) {
27
+ tokenFormRequestBody.append('client_id', clientId)
28
+ tokenFormRequestBody.append('client_secret', clientSecret)
29
+ tokenFormRequestBody.append('grant_type', 'client_credentials')
30
+ } else {
31
+ throw new Error(
32
+ 'Authentication failed, either the RefreshToken, or ClientId and ClientSecret need to be provided'
33
+ )
34
+ }
35
+
36
+ const response = await this.axiosTokenInstance.post(
37
+ '/services/oauth2/token',
38
+ tokenFormRequestBody,
39
+ {
40
+ headers: tokenFormRequestBody.getHeaders()
41
+ }
42
+ )
43
+
44
+ this.token = response?.data?.['access_token']
45
+ if (!this.token) throw new Error('Authentication failed, could not get the access token')
46
+ return this.token
47
+ }
48
+ }
@@ -0,0 +1,42 @@
1
+ import { AxiosInstance } from 'axios'
2
+ import { Practitioner } from '../../models/practitioner'
3
+ import { SF_API_VERSION } from '../apiClient'
4
+
5
+ export class SFPractitionerClient {
6
+ private axiosInstance: AxiosInstance
7
+
8
+ constructor(axiosInstance: AxiosInstance) {
9
+ this.axiosInstance = axiosInstance
10
+ }
11
+
12
+ async fetchPractitioners(): Promise<Practitioner[]> {
13
+ try {
14
+ const url = `/services/data/${SF_API_VERSION}/query`
15
+ const query = `
16
+ SELECT Id, FirstName__c, LastName__c, Email__c, StaffID__c
17
+ FROM Personnel__c
18
+ WHERE Status__c = 'Active'
19
+ `
20
+ const {
21
+ data: { records }
22
+ } = await this.axiosInstance.get(url, {
23
+ params: { q: query }
24
+ })
25
+
26
+ return records.map(toPractitioner)
27
+ } catch (error) {
28
+ console.error('Error fetching practitioners: ', error.message)
29
+ throw error
30
+ }
31
+ }
32
+ }
33
+
34
+ function toPractitioner(raw: any): Practitioner {
35
+ return {
36
+ id: raw.Id,
37
+ firstName: raw.FirstName__c,
38
+ lastName: raw.LastName__c,
39
+ email: raw.Email__c,
40
+ staffId: raw.StaffID__c
41
+ }
42
+ }
@@ -0,0 +1,98 @@
1
+ import { AxiosInstance } from 'axios'
2
+ import { TimesheetDayEntry } from '../../models'
3
+ import { SF_API_VERSION } from '../apiClient'
4
+
5
+ export class SFTimesheetClient {
6
+ private axiosInstance: AxiosInstance
7
+
8
+ constructor(axiosInstance: AxiosInstance) {
9
+ this.axiosInstance = axiosInstance
10
+ }
11
+
12
+ async updateTimesheetHour(timesheetHourId: string, timesheet: TimesheetDayEntry) {
13
+ try {
14
+ const url = `/services/data/${SF_API_VERSION}/sobjects/TimeSheetHour__c/${timesheetHourId}`
15
+ const response = await this.axiosInstance.patch(url, {
16
+ Date__c: timesheet.date,
17
+ Callback__c: timesheet.callbackHours,
18
+ HoursEBAdjusted__c: timesheet.regularHours,
19
+ Misc__c: timesheet.miscHours,
20
+ OT1__c: timesheet.overtime1Hours,
21
+ OT2__c: timesheet.overtime2Hours,
22
+ OnCall__c: timesheet.onCallHours,
23
+ Misc1__c: timesheet.misc1HoursA,
24
+ Misc_1_Hours__c: timesheet.misc1HoursB,
25
+ Misc_2_Hours__c: timesheet.misc2Hours,
26
+ Misc_3_Hours__c: timesheet.misc3Hours,
27
+ Misc_4_Hours__c: timesheet.misc4Hours,
28
+ Stat1__c: timesheet.stat1Hours,
29
+ Stat2__c: timesheet.stat2Hours,
30
+ In_Charge__c: timesheet.inChargeHours,
31
+ Shift_Travel_Stipend__c: timesheet.shiftTravelPerDiemHours
32
+ })
33
+
34
+ if (![200, 204, 304].includes(response.status))
35
+ throw new Error(`got error status code ${response.status}`)
36
+ } catch (error) {
37
+ console.error('Error Updating Timesheet Hour: ', error.message)
38
+ }
39
+ }
40
+
41
+ async getTimesheetId(workorderId: string): Promise<string> {
42
+ // First we find the correct timesheet id
43
+ const url = `/services/data/${SF_API_VERSION}/query`
44
+ const query = `SELECT Id FROM Timesheet__c WHERE WorkOrder__c = '${workorderId}' LIMIT 1`
45
+ const {
46
+ data: { records }
47
+ } = await this.axiosInstance.get(url, {
48
+ params: { q: query }
49
+ })
50
+ return records[0].Id
51
+ }
52
+
53
+ async getTimesheetHoursIds(workorderId: string): Promise<string[]> {
54
+ const timesheetId = await this.getTimesheetId(workorderId)
55
+ // First we find the correct timesheet hours id
56
+ const url = `/services/data/${SF_API_VERSION}/query`
57
+ const query = `SELECT Id FROM TimesheetHour__c WHERE Timesheet__c = '${timesheetId}'`
58
+ const {
59
+ data: { records }
60
+ } = await this.axiosInstance.get(url, {
61
+ params: { q: query }
62
+ })
63
+ return records.map(({ Id }) => Id)
64
+ }
65
+
66
+ async getTimesheetHours(workorderId: string): Promise<TimesheetDayEntry[]> {
67
+ const timesheetHourIds = await this.getTimesheetHoursIds(workorderId)
68
+ return Promise.all(
69
+ timesheetHourIds.map(async id =>
70
+ this.axiosInstance
71
+ .get(`/services/data/${SF_API_VERSION}/sobjects/TimeSheetHour__c/${id}`)
72
+ .then(res => res.data)
73
+ .then(toTimesheetDayEntry)
74
+ )
75
+ )
76
+ }
77
+ }
78
+
79
+ function toTimesheetDayEntry(raw: any): TimesheetDayEntry {
80
+ return {
81
+ date: raw.Date__c,
82
+ callbackHours: raw.Callback__c,
83
+ regularHours: raw.HoursEBAdjusted__c,
84
+ miscHours: raw.Misc__c,
85
+ overtime1Hours: raw.OT1__c,
86
+ overtime2Hours: raw.OT2__c,
87
+ onCallHours: raw.OnCall__c,
88
+ misc1HoursA: raw.Misc1__c,
89
+ misc1HoursB: raw.Misc_1_Hours__c,
90
+ misc2Hours: raw.Misc_2_Hours__c,
91
+ misc3Hours: raw.Misc_3_Hours__c,
92
+ misc4Hours: raw.Misc_4_Hours__c,
93
+ stat1Hours: raw.Stat1__c,
94
+ stat2Hours: raw.Stat2__c,
95
+ inChargeHours: raw.In_Charge__c,
96
+ shiftTravelPerDiemHours: raw.Shift_Travel_Stipend__c
97
+ }
98
+ }
package/src/index.ts ADDED
@@ -0,0 +1,3 @@
1
+ export * from './api/apiClient'
2
+ export * from './api/timesheet/timesheetClient'
3
+ export * from './api/auth/auth'
@@ -0,0 +1,14 @@
1
+ export interface Role {
2
+ label: string
3
+ value: string
4
+ }
5
+
6
+ export interface Workorder {
7
+ id: string
8
+ establishmentName: string
9
+ establishmentId: string
10
+ role: string
11
+ }
12
+
13
+ export * from './timesheet'
14
+ export * from './practitioner'
@@ -0,0 +1,7 @@
1
+ export interface Practitioner {
2
+ id: string
3
+ firstName: string
4
+ lastName: string
5
+ email: string
6
+ staffId: string
7
+ }
@@ -0,0 +1,21 @@
1
+ export interface TimesheetDayEntry {
2
+ date?: Date
3
+ callbackHours?: number
4
+ regularHours?: number
5
+ miscHours?: number
6
+ overtime1Hours?: number
7
+ overtime2Hours?: number
8
+ onCallHours?: number
9
+ misc1HoursA?: number
10
+ misc1HoursB?: number
11
+ misc2Hours?: number
12
+ misc3Hours?: number
13
+ misc4Hours?: number
14
+ stat1Hours?: number
15
+ stat2Hours?: number
16
+ // "EmployeeTimeCardEntry__c": null, // unknown entry in salesforce
17
+ inChargeHours?: number
18
+ // "Shift_Differential__c": number, // unknown entry in salesforce
19
+ shiftTravelPerDiemHours?: number
20
+ // "Weekend_Differential__c": number // unknown entry in salesforce
21
+ }