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.
@@ -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
- }): Promise<Practitioner[]> {
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 Id, FirstName__c, LastName__c, Email__c, StaffID__c, CreatedDate
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 records.map(toPractitioner)
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
+ }
@@ -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