pha-hermes 1.27.0 → 1.29.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/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.27.0",
2
+ "version": "1.29.0",
3
3
  "main": "dist/index.js",
4
4
  "typings": "dist/index.d.ts",
5
5
  "files": [
@@ -75,7 +75,16 @@ export class LipheAuthenticator {
75
75
  const response = await this.axiosTokenInstance.post('v2/signin', form, {
76
76
  headers: form.getHeaders()
77
77
  })
78
- const token = response?.data?.data?.token
78
+
79
+ let responseData = response.data
80
+ if (typeof responseData === 'string') {
81
+ const jsonMatch = responseData.match(/^\{.*?}(?=HTTP|$)/)
82
+ if (jsonMatch) {
83
+ responseData = JSON.parse(jsonMatch[0])
84
+ }
85
+ }
86
+
87
+ const token = responseData?.data?.token
79
88
  if (!token) {
80
89
  throw new Error('Authentication failed: no token return')
81
90
  }
@@ -2,6 +2,7 @@ import axios, { AxiosInstance } from 'axios'
2
2
  import { LipheAuthenticator } from './auth/authClient'
3
3
  import { LiphePractitionerClient } from './practitioner/practitionerClient'
4
4
  import { ContractRequestPeriodClient } from './contract_request_period/contractRequestPeriodClient'
5
+ import { TimesheetClient } from './timesheets/timesheetClient'
5
6
  import axiosRetry from 'axios-retry'
6
7
 
7
8
  export class LipheApiClient {
@@ -10,6 +11,7 @@ export class LipheApiClient {
10
11
  private authenticator: LipheAuthenticator
11
12
  public practitionerClient: LiphePractitionerClient
12
13
  public contractRequestPeriodClient: ContractRequestPeriodClient
14
+ public timesheetClient: TimesheetClient
13
15
 
14
16
  constructor(
15
17
  baseUrl: string,
@@ -39,6 +41,7 @@ export class LipheApiClient {
39
41
 
40
42
  this.practitionerClient = new LiphePractitionerClient(this.axiosInstance)
41
43
  this.contractRequestPeriodClient = new ContractRequestPeriodClient(this.axiosInstance)
44
+ this.timesheetClient = new TimesheetClient(this.axiosInstance)
42
45
  }
43
46
  async init() {
44
47
  await this.authenticator.initializeAuth()
@@ -0,0 +1,101 @@
1
+ import type { AxiosInstance } from 'axios'
2
+ import FormData from 'form-data'
3
+
4
+ export interface TimesheetParams {
5
+ workorder_id: string
6
+ start: Date
7
+ end: Date
8
+ }
9
+
10
+ export interface CallbackTimesheetParams extends TimesheetParams {
11
+ reason: string
12
+ }
13
+
14
+ export interface StandbyTimesheetParams extends TimesheetParams {
15
+ calls_order: string
16
+ }
17
+
18
+ export const TimesheetType = {
19
+ Regular: 'regular',
20
+ Callback: 'callback',
21
+ Overtime: 'overtime',
22
+ Standby: 'standby'
23
+ } as const
24
+
25
+ export interface TimesheetResponse {
26
+ success: boolean
27
+ data?: any
28
+ error?: string
29
+ }
30
+
31
+ export class TimesheetClient {
32
+ private axios: AxiosInstance
33
+
34
+ constructor(axiosInstance: AxiosInstance) {
35
+ this.axios = axiosInstance
36
+ }
37
+
38
+ async sendRegularTimesheet(params: TimesheetParams): Promise<TimesheetResponse> {
39
+ return this.sendTimesheet(TimesheetType.Regular, params)
40
+ }
41
+
42
+ async sendCallbackTimesheet(params: CallbackTimesheetParams): Promise<TimesheetResponse> {
43
+ return this.sendTimesheet(TimesheetType.Callback, params)
44
+ }
45
+
46
+ async sendOvertimeTimesheet(params: TimesheetParams): Promise<TimesheetResponse> {
47
+ return this.sendTimesheet(TimesheetType.Overtime, params)
48
+ }
49
+
50
+ async sendStandbyTimesheet(params: StandbyTimesheetParams): Promise<TimesheetResponse> {
51
+ return this.sendTimesheet(TimesheetType.Standby, params)
52
+ }
53
+
54
+ private async sendTimesheet(
55
+ type: (typeof TimesheetType)[keyof typeof TimesheetType],
56
+ params: TimesheetParams | CallbackTimesheetParams | StandbyTimesheetParams
57
+ ): Promise<TimesheetResponse> {
58
+ try {
59
+ const form = new FormData()
60
+ form.append('workorder_id', params.workorder_id)
61
+ form.append('start', this.formatDateTime(params.start))
62
+ form.append('end', this.formatDateTime(params.end))
63
+
64
+ if (type === TimesheetType.Callback && 'reason' in params) {
65
+ form.append('reason', params.reason)
66
+ }
67
+
68
+ if (type === TimesheetType.Standby && 'calls_order' in params) {
69
+ form.append('calls_order', params.calls_order)
70
+ }
71
+
72
+ const response = await this.axios.post(`v3/workorderLog/${type}`, form, {
73
+ headers: form.getHeaders()
74
+ })
75
+
76
+ return {
77
+ success: true,
78
+ data: response.data
79
+ }
80
+ } catch (error) {
81
+ return {
82
+ success: false,
83
+ error: error.message || 'Failed to send timesheet',
84
+ data: error.response?.data
85
+ }
86
+ }
87
+ }
88
+
89
+ /**
90
+ * Converts a Date object to the required string format: "YYYY-MM-DD HH:mm"
91
+ */
92
+ private formatDateTime(date: Date): string {
93
+ const year = date.getFullYear()
94
+ const month = String(date.getMonth() + 1).padStart(2, '0')
95
+ const day = String(date.getDate()).padStart(2, '0')
96
+ const hours = String(date.getHours()).padStart(2, '0')
97
+ const minutes = String(date.getMinutes()).padStart(2, '0')
98
+
99
+ return `${year}-${month}-${day} ${hours}:${minutes}`
100
+ }
101
+ }
@@ -1,4 +1,4 @@
1
- import { AxiosInstance } from "axios"
1
+ import { AxiosInstance } from 'axios'
2
2
 
3
3
  export interface Account {
4
4
  id: string
@@ -16,6 +16,7 @@ export interface Account {
16
16
  fax: string | null
17
17
  email: string
18
18
  lang: 'eng' | 'fra'
19
+ clientNumber: string
19
20
  }
20
21
 
21
22
  export interface HealthAuthority extends Account {
@@ -39,7 +40,8 @@ const ACCOUNT_FIELDS = [
39
40
  'BillingAddress',
40
41
  'Phone',
41
42
  'Fax',
42
- 'Type'
43
+ 'Type',
44
+ 'Client_Number__c'
43
45
  ] as const
44
46
 
45
47
  export class SFAccounts {
@@ -49,7 +51,10 @@ export class SFAccounts {
49
51
  this.axiosInstance = axiosInstance
50
52
  }
51
53
 
52
- async fetchAccounts<T extends Account>(type: AccountType, options?: { parentId?: string, active?: boolean, failfast?: boolean }): Promise<T[]> {
54
+ async fetchAccounts<T extends Account>(
55
+ type: AccountType,
56
+ options?: { parentId?: string; active?: boolean; failfast?: boolean }
57
+ ): Promise<T[]> {
53
58
  try {
54
59
  let accountType: 'Health Authority' | 'Hospital'
55
60
  switch (type) {
@@ -68,7 +73,9 @@ export class SFAccounts {
68
73
  let done = false
69
74
  let url = `/services/data/v57.0/query`
70
75
  do {
71
- const { data: { records: pageRecords, nextRecordsUrl, done: isDone } } = await this.axiosInstance.get(url, { params: { q: query } })
76
+ const {
77
+ data: { records: pageRecords, nextRecordsUrl, done: isDone }
78
+ } = await this.axiosInstance.get(url, { params: { q: query } })
72
79
  records.push(...pageRecords)
73
80
  done = isDone
74
81
  url = nextRecordsUrl
@@ -77,13 +84,16 @@ export class SFAccounts {
77
84
 
78
85
  for (const i in accounts)
79
86
  if (accounts[i].accountTypeName === 'healthAuthority')
80
- (accounts[i] as HealthAuthority).children = await this.fetchAccounts<Establishment>('establishment', { parentId: accounts[i].id, active: options?.active })
87
+ (accounts[i] as HealthAuthority).children =
88
+ await this.fetchAccounts<Establishment>('establishment', {
89
+ parentId: accounts[i].id,
90
+ active: options?.active
91
+ })
81
92
 
82
93
  return accounts as T[]
83
94
  } catch (error) {
84
95
  console.error(`Error fetching ${type} accounts: `, error.message)
85
- if (options?.failfast)
86
- throw error
96
+ if (options?.failfast) throw error
87
97
  return []
88
98
  }
89
99
  }
@@ -119,7 +129,8 @@ export class SFAccounts {
119
129
  email: null,
120
130
  phone2: null,
121
131
  cellular: null,
122
- lang: 'eng'
132
+ lang: 'eng',
133
+ clientNumber: record.Client_Number__c
123
134
  }
124
135
  }
125
- }
136
+ }