pha-hermes 1.24.0 → 1.26.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.
- package/dist/api/salesforce/accounts/accounts.d.ts +38 -0
- package/dist/api/salesforce/apiClient.d.ts +2 -0
- package/dist/api/salesforce/practitioner/practitionerClient.d.ts +8 -1
- package/dist/models/user.d.ts +13 -0
- package/dist/pha-hermes.cjs.development.js +166 -11
- package/dist/pha-hermes.cjs.development.js.map +1 -1
- package/dist/pha-hermes.cjs.production.min.js +1 -1
- package/dist/pha-hermes.cjs.production.min.js.map +1 -1
- package/dist/pha-hermes.esm.js +166 -11
- package/dist/pha-hermes.esm.js.map +1 -1
- package/package.json +1 -1
- package/src/api/salesforce/accounts/accounts.ts +121 -0
- package/src/api/salesforce/apiClient.ts +3 -0
- package/src/api/salesforce/practitioner/practitionerClient.ts +65 -4
- package/src/models/user.ts +14 -0
- package/src/api/.env +0 -5
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { AxiosInstance } from "axios"
|
|
2
|
+
|
|
3
|
+
export interface Account {
|
|
4
|
+
id: string
|
|
5
|
+
name: string
|
|
6
|
+
accountTypeName: AccountType
|
|
7
|
+
regionName: string
|
|
8
|
+
geographicalAreaName: string | null
|
|
9
|
+
address: string | null
|
|
10
|
+
city: string | null
|
|
11
|
+
province: string | null
|
|
12
|
+
postalCode: string | null
|
|
13
|
+
phone: string | null
|
|
14
|
+
phone2: string | null
|
|
15
|
+
cellular: string | null
|
|
16
|
+
fax: string | null
|
|
17
|
+
email: string
|
|
18
|
+
lang: 'eng' | 'fra'
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface HealthAuthority extends Account {
|
|
22
|
+
accountTypeName: 'healthAuthority'
|
|
23
|
+
children: Establishment[]
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface Establishment extends Account {
|
|
27
|
+
accountTypeName: 'establishment'
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
type AccountType = 'healthAuthority' | 'establishment'
|
|
31
|
+
|
|
32
|
+
const ACCOUNT_FIELDS = [
|
|
33
|
+
'Id',
|
|
34
|
+
'Name',
|
|
35
|
+
'BillingCity',
|
|
36
|
+
'BillingState',
|
|
37
|
+
'BillingPostalCode',
|
|
38
|
+
'BillingCountry',
|
|
39
|
+
'BillingAddress',
|
|
40
|
+
'Phone',
|
|
41
|
+
'Fax',
|
|
42
|
+
'Type'
|
|
43
|
+
] as const
|
|
44
|
+
|
|
45
|
+
export class SFAccounts {
|
|
46
|
+
private axiosInstance: AxiosInstance
|
|
47
|
+
|
|
48
|
+
constructor(axiosInstance: AxiosInstance) {
|
|
49
|
+
this.axiosInstance = axiosInstance
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
async fetchAccounts<T extends Account>(type: AccountType, options?: { parentId?: string, pageSize?: number, pageNumber?: number, failfast?: boolean }): Promise<T[]> {
|
|
53
|
+
try {
|
|
54
|
+
let accountType: 'Health Authority' | 'Hospital'
|
|
55
|
+
switch (type) {
|
|
56
|
+
case 'healthAuthority':
|
|
57
|
+
accountType = 'Health Authority'
|
|
58
|
+
break
|
|
59
|
+
case 'establishment':
|
|
60
|
+
accountType = 'Hospital'
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
let query = `SELECT ${ACCOUNT_FIELDS.join(',')} FROM Account WHERE Type = '${accountType}'`
|
|
64
|
+
if (options?.parentId) query += ` AND ParentId = '${options.parentId}'`
|
|
65
|
+
if (options?.pageSize) query += ` LIMIT ${options.pageSize}`
|
|
66
|
+
if (options?.pageNumber) query += ` OFFSET ${options.pageNumber * options.pageSize}`
|
|
67
|
+
|
|
68
|
+
const response = await this.axiosInstance.get(`/services/data/v57.0/query?q=${query}`)
|
|
69
|
+
const accounts: Account[] = response.data.records.map(record => this.buildAccount(record))
|
|
70
|
+
|
|
71
|
+
for (const i in accounts) {
|
|
72
|
+
if (accounts[i].accountTypeName === 'healthAuthority') {
|
|
73
|
+
let pageNumber = 0
|
|
74
|
+
const childAccounts = []
|
|
75
|
+
let returnedPageSize = 0
|
|
76
|
+
do {
|
|
77
|
+
const pageAccounts = await this.fetchAccounts<Establishment>('establishment', { parentId: accounts[i].id, pageSize: options?.pageSize ?? 100, pageNumber, failfast: options?.failfast })
|
|
78
|
+
childAccounts.push(...pageAccounts)
|
|
79
|
+
returnedPageSize = pageAccounts.length
|
|
80
|
+
pageNumber++
|
|
81
|
+
} while (returnedPageSize > 0);
|
|
82
|
+
(accounts[i] as HealthAuthority).children = childAccounts
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return accounts as T[]
|
|
86
|
+
} catch (error) {
|
|
87
|
+
console.error(`Error fetching ${type}s: `, error.message)
|
|
88
|
+
if (options?.failfast)
|
|
89
|
+
throw error
|
|
90
|
+
return []
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
private buildAccount(record: any): Account {
|
|
94
|
+
let accountType: AccountType
|
|
95
|
+
|
|
96
|
+
switch (record.Type) {
|
|
97
|
+
case 'Health Authority':
|
|
98
|
+
accountType = 'healthAuthority'
|
|
99
|
+
break
|
|
100
|
+
case 'Hospital':
|
|
101
|
+
accountType = 'establishment'
|
|
102
|
+
}
|
|
103
|
+
return {
|
|
104
|
+
id: record.Id,
|
|
105
|
+
name: record.Name,
|
|
106
|
+
address: record.BillingAddress,
|
|
107
|
+
city: record.BillingCity,
|
|
108
|
+
province: record.BillingState,
|
|
109
|
+
postalCode: record.BillingPostalCode,
|
|
110
|
+
geographicalAreaName: record.BillingGeocodeAccuracy,
|
|
111
|
+
phone: record.Phone,
|
|
112
|
+
fax: record.Fax,
|
|
113
|
+
regionName: record.RegionName,
|
|
114
|
+
accountTypeName: accountType,
|
|
115
|
+
email: null,
|
|
116
|
+
phone2: null,
|
|
117
|
+
cellular: null,
|
|
118
|
+
lang: 'eng'
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
@@ -7,6 +7,7 @@ import { SFWorkorderClient } from './workorder/workorderClient'
|
|
|
7
7
|
import { SFPayPeriodClient } from './payperiod/payperiodClient'
|
|
8
8
|
import { SFExpenseClient } from './expenses/expenseClient'
|
|
9
9
|
import { SFPriceClient } from './prices/priceClient'
|
|
10
|
+
import { SFAccounts } from './accounts/accounts'
|
|
10
11
|
|
|
11
12
|
export const SF_API_VERSION: string = 'v57.0'
|
|
12
13
|
|
|
@@ -21,6 +22,7 @@ export class SFApiClient {
|
|
|
21
22
|
payPeriodClient: SFPayPeriodClient
|
|
22
23
|
expenseClient: SFExpenseClient
|
|
23
24
|
priceClient: SFPriceClient
|
|
25
|
+
accountsClient: SFAccounts
|
|
24
26
|
|
|
25
27
|
async init(
|
|
26
28
|
baseUrl: string,
|
|
@@ -37,6 +39,7 @@ export class SFApiClient {
|
|
|
37
39
|
this.payPeriodClient = new SFPayPeriodClient(this.axiosInstance)
|
|
38
40
|
this.expenseClient = new SFExpenseClient(this.axiosInstance)
|
|
39
41
|
this.priceClient = new SFPriceClient(this.axiosInstance)
|
|
42
|
+
this.accountsClient = new SFAccounts(this.axiosInstance)
|
|
40
43
|
// creates authenticator and adds token to axios instance
|
|
41
44
|
await this.authenticator.initializeAuth(sfClientId, sfClientSecret, onTokenRefresh)
|
|
42
45
|
}
|
|
@@ -1,18 +1,54 @@
|
|
|
1
1
|
import { AxiosInstance } from 'axios'
|
|
2
|
-
import { Practitioner, Role } from '../../../models'
|
|
2
|
+
import { Practitioner, PractitionerExport, Role } from '../../../models'
|
|
3
3
|
import { SF_API_VERSION } from '../../../index'
|
|
4
4
|
|
|
5
5
|
export class SFPractitionerClient {
|
|
6
|
+
private PRACTITIONER_FIELDS = {
|
|
7
|
+
default: ['Id', 'FirstName__c', 'LastName__c', 'Email__c', 'StaffID__c', 'CreatedDate'],
|
|
8
|
+
export: [
|
|
9
|
+
'Id',
|
|
10
|
+
'FirstName__c',
|
|
11
|
+
'LastName__c',
|
|
12
|
+
'Email__c',
|
|
13
|
+
'StaffID__c',
|
|
14
|
+
'CreatedDate',
|
|
15
|
+
'DaytimePhone__c',
|
|
16
|
+
'Status__c',
|
|
17
|
+
'ProfessionalDesignation__c',
|
|
18
|
+
'CANSocialInsuranceNumber__c',
|
|
19
|
+
'Date_of_Hire__c',
|
|
20
|
+
'DateApplied__c',
|
|
21
|
+
'Birthdate__c',
|
|
22
|
+
'MailingStreetAddress__c',
|
|
23
|
+
'MailingCity__c',
|
|
24
|
+
'MailingStateProvince__c',
|
|
25
|
+
'MailingZipPostalCode__c'
|
|
26
|
+
]
|
|
27
|
+
} as const
|
|
28
|
+
|
|
6
29
|
private axiosInstance: AxiosInstance
|
|
7
30
|
|
|
8
31
|
constructor(axiosInstance: AxiosInstance) {
|
|
9
32
|
this.axiosInstance = axiosInstance
|
|
10
33
|
}
|
|
11
34
|
|
|
35
|
+
async fetchPractitioners(options: {
|
|
36
|
+
createdAt?: string
|
|
37
|
+
limit?: number
|
|
38
|
+
forExport: true
|
|
39
|
+
}): Promise<PractitionerExport[]>
|
|
40
|
+
|
|
41
|
+
async fetchPractitioners(options?: {
|
|
42
|
+
createdAt?: string
|
|
43
|
+
limit?: number
|
|
44
|
+
forExport?: false | undefined
|
|
45
|
+
}): Promise<Practitioner[]>
|
|
46
|
+
|
|
12
47
|
async fetchPractitioners(options?: {
|
|
13
48
|
createdAt?: string
|
|
14
49
|
limit?: number
|
|
15
|
-
|
|
50
|
+
forExport?: boolean
|
|
51
|
+
}): Promise<Practitioner[] | PractitionerExport[]> {
|
|
16
52
|
try {
|
|
17
53
|
const conditions: string[] = [`Status__c = 'Active'`]
|
|
18
54
|
if (options?.createdAt) {
|
|
@@ -24,8 +60,14 @@ export class SFPractitionerClient {
|
|
|
24
60
|
? `LIMIT ${Math.floor(options.limit)}`
|
|
25
61
|
: ''
|
|
26
62
|
const url = `/services/data/${SF_API_VERSION}/query`
|
|
63
|
+
const fields = (
|
|
64
|
+
options?.forExport
|
|
65
|
+
? this.PRACTITIONER_FIELDS.export
|
|
66
|
+
: this.PRACTITIONER_FIELDS.default
|
|
67
|
+
).join(', ')
|
|
68
|
+
|
|
27
69
|
const query = `
|
|
28
|
-
SELECT
|
|
70
|
+
SELECT ${fields}
|
|
29
71
|
FROM Personnel__c
|
|
30
72
|
${whereClause}
|
|
31
73
|
ORDER BY CreatedDate ASC, StaffID__c ASC
|
|
@@ -37,7 +79,9 @@ export class SFPractitionerClient {
|
|
|
37
79
|
params: { q: query }
|
|
38
80
|
})
|
|
39
81
|
|
|
40
|
-
return
|
|
82
|
+
return options?.forExport
|
|
83
|
+
? records.map(toPractitionerExport)
|
|
84
|
+
: records.map(toPractitioner)
|
|
41
85
|
} catch (error) {
|
|
42
86
|
console.error('Error fetching practitioners: ', error.message)
|
|
43
87
|
throw error
|
|
@@ -107,3 +151,20 @@ function toPractitioner(raw: any): Practitioner {
|
|
|
107
151
|
createdAt: raw.CreatedDate ? raw.CreatedDate.replace(/\+0000$/, 'Z') : undefined
|
|
108
152
|
}
|
|
109
153
|
}
|
|
154
|
+
|
|
155
|
+
function toPractitionerExport(raw: any): PractitionerExport {
|
|
156
|
+
return {
|
|
157
|
+
...toPractitioner(raw),
|
|
158
|
+
phone: raw.DaytimePhone__c,
|
|
159
|
+
status: raw.Status__c,
|
|
160
|
+
professionalDesignation: raw.ProfessionalDesignation__c,
|
|
161
|
+
SIN: raw.CANSocialInsuranceNumber__c,
|
|
162
|
+
hiringDate: raw.Date_of_Hire__c,
|
|
163
|
+
dateApplied: raw.DateApplied__c,
|
|
164
|
+
birthdate: raw.Birthdate__c,
|
|
165
|
+
mailingStreetAddress: raw.MailingStreetAddress__c,
|
|
166
|
+
mailingCity: raw.MailingCity__c,
|
|
167
|
+
mailingProvince: raw.MailingStateProvince__c,
|
|
168
|
+
mailingZip: raw.MailingZipPostalCode__c
|
|
169
|
+
}
|
|
170
|
+
}
|
package/src/models/user.ts
CHANGED
|
@@ -7,6 +7,20 @@ export interface Practitioner {
|
|
|
7
7
|
createdAt?: string
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
+
export interface PractitionerExport extends Practitioner {
|
|
11
|
+
phone: string | null
|
|
12
|
+
status: string | null
|
|
13
|
+
professionalDesignation: string | null
|
|
14
|
+
SIN: string | null
|
|
15
|
+
hiringDate: string | null
|
|
16
|
+
dateApplied: string | null
|
|
17
|
+
birthdate: string | null
|
|
18
|
+
mailingStreetAddress: string | null
|
|
19
|
+
mailingCity: string | null
|
|
20
|
+
mailingProvince: string | null
|
|
21
|
+
mailingZip: string | null
|
|
22
|
+
}
|
|
23
|
+
|
|
10
24
|
export interface Role {
|
|
11
25
|
label: string
|
|
12
26
|
value: string
|
package/src/api/.env
DELETED
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
I THINK THIS ONE IS WRONG
|
|
2
|
-
SF_CLIENT_ID=3MVG9TZvGM_0NqB09H2fPRxeiDEsovly3D10kwNjOYJNTwBhMc5JHQgCdaSM.2N1V04tb_Tuyj_qktBPNueQd
|
|
3
|
-
SF_CLIENT_SECRET=6F4D40003CF5B156A2AD2BFAD384E74AA9FFFD574E8753EAC485E3C478C50F9F
|
|
4
|
-
GRANT_TYPE=client_credentials
|
|
5
|
-
SALESFORCE_URL=https://do0000000d247eaa--phealth.sandbox.my.salesforce.com
|