@worknice/js-sdk 0.0.3 → 0.0.5

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.
Files changed (135) hide show
  1. package/dist/{_types-BXw9D0Qi.d.ts → _types-kBsjg67t.d.ts} +57 -2
  2. package/dist/api/ApiError.d.ts +2 -1
  3. package/dist/api/ApiError.js +4 -2
  4. package/dist/api/ApiError.js.map +1 -1
  5. package/dist/api/WorkniceIntegrationLogger.d.ts +41 -17
  6. package/dist/api/WorkniceIntegrationLogger.js +58 -28
  7. package/dist/api/WorkniceIntegrationLogger.js.map +1 -1
  8. package/dist/api/_generated.d.ts +183 -68
  9. package/dist/api/_generated.js +2 -0
  10. package/dist/api/_generated.js.map +1 -1
  11. package/dist/api/_types.d.ts +2 -2
  12. package/dist/api/createApiOperation.d.ts +1 -1
  13. package/dist/api/createWorkniceClient.d.ts +1 -1
  14. package/dist/api/createWorkniceClient.js +2 -0
  15. package/dist/api/createWorkniceClient.js.map +1 -1
  16. package/dist/api/operations/activateIntegration.d.ts +1 -1
  17. package/dist/api/operations/authorizeIntegration.d.ts +1 -1
  18. package/dist/api/operations/completeSync.d.ts +1 -1
  19. package/dist/api/operations/createApiToken.d.ts +1 -1
  20. package/dist/api/operations/createDataImport.d.ts +1 -1
  21. package/dist/api/operations/createPersonConnection.d.ts +8 -1
  22. package/dist/api/operations/createPersonConnection.js +1 -0
  23. package/dist/api/operations/createPersonConnection.js.map +1 -1
  24. package/dist/api/operations/createPersonDataImportLine.d.ts +7 -3
  25. package/dist/api/operations/createPersonDataImportLine.js +10 -2
  26. package/dist/api/operations/createPersonDataImportLine.js.map +1 -1
  27. package/dist/api/operations/deleteApiToken.d.ts +1 -1
  28. package/dist/api/operations/deletePersonConnection.d.ts +1 -1
  29. package/dist/api/operations/getApiTokens.d.ts +1 -1
  30. package/dist/api/operations/getApiTokens.js +7 -1
  31. package/dist/api/operations/getApiTokens.js.map +1 -1
  32. package/dist/api/operations/getIntegration.d.ts +1 -1
  33. package/dist/api/operations/getMyApps.d.ts +37 -0
  34. package/dist/api/operations/getMyApps.js +62 -0
  35. package/dist/api/operations/getMyApps.js.map +1 -0
  36. package/dist/api/operations/getPeople.d.ts +1 -1
  37. package/dist/api/operations/getPersonConnections.d.ts +8 -1
  38. package/dist/api/operations/getPersonConnections.js +1 -0
  39. package/dist/api/operations/getPersonConnections.js.map +1 -1
  40. package/dist/api/operations/initializeIntegration.d.ts +1 -1
  41. package/dist/api/operations/updatePersonConnection.d.ts +8 -1
  42. package/dist/api/operations/updatePersonConnection.js +1 -0
  43. package/dist/api/operations/updatePersonConnection.js.map +1 -1
  44. package/dist/employee-records/EQUALITY_CHECKS.js +23 -11
  45. package/dist/employee-records/EQUALITY_CHECKS.js.map +1 -1
  46. package/dist/employee-records/_types.d.ts +169 -149
  47. package/dist/employee-records/comparePersonDataTransferLines.js +61 -13
  48. package/dist/employee-records/comparePersonDataTransferLines.js.map +1 -1
  49. package/dist/employee-records/index.d.ts +9 -6
  50. package/dist/employee-records/index.js +22 -14
  51. package/dist/employee-records/index.js.map +1 -1
  52. package/dist/employee-records/mergePersonDataTransferLines.js +5 -9
  53. package/dist/employee-records/mergePersonDataTransferLines.js.map +1 -1
  54. package/dist/employee-records/validatePersonDataTransferLine.js +10 -2
  55. package/dist/employee-records/validatePersonDataTransferLine.js.map +1 -1
  56. package/dist/employee-records/validatePersonDataTransferLineDateOfBirth.d.ts +6 -0
  57. package/dist/employee-records/validatePersonDataTransferLineDateOfBirth.js +17 -0
  58. package/dist/employee-records/validatePersonDataTransferLineDateOfBirth.js.map +1 -0
  59. package/dist/employee-records/validatePersonDataTransferLineFullName.d.ts +6 -0
  60. package/dist/employee-records/validatePersonDataTransferLineFullName.js +20 -0
  61. package/dist/employee-records/validatePersonDataTransferLineFullName.js.map +1 -0
  62. package/dist/employee-records/validatePersonDataTransferLineGender.d.ts +6 -0
  63. package/dist/employee-records/validatePersonDataTransferLineGender.js +13 -0
  64. package/dist/employee-records/validatePersonDataTransferLineGender.js.map +1 -0
  65. package/dist/employee-records/validatePersonDataTransferLinePersonalEmail.d.ts +6 -0
  66. package/dist/employee-records/validatePersonDataTransferLinePersonalEmail.js +15 -0
  67. package/dist/employee-records/validatePersonDataTransferLinePersonalEmail.js.map +1 -0
  68. package/dist/employee-records/validatePersonDataTransferLinePersonalPhone.d.ts +6 -0
  69. package/dist/employee-records/validatePersonDataTransferLinePersonalPhone.js +15 -0
  70. package/dist/employee-records/validatePersonDataTransferLinePersonalPhone.js.map +1 -0
  71. package/dist/employee-records/validatePersonDataTransferLineTenure.js +1 -1
  72. package/dist/employee-records/validatePersonDataTransferLineTenure.js.map +1 -1
  73. package/dist/helpers/_types.d.ts +7 -3
  74. package/dist/helpers/handleApproveLeaveRequestWebhook.d.ts +15 -0
  75. package/dist/helpers/handleApproveLeaveRequestWebhook.js +21 -0
  76. package/dist/helpers/handleApproveLeaveRequestWebhook.js.map +1 -0
  77. package/dist/helpers/handleCancelLeaveRequestWebhook.d.ts +15 -0
  78. package/dist/helpers/handleCancelLeaveRequestWebhook.js +21 -0
  79. package/dist/helpers/handleCancelLeaveRequestWebhook.js.map +1 -0
  80. package/dist/helpers/handleCreateIntegrationWebhook.d.ts +4 -4
  81. package/dist/helpers/handleCreateIntegrationWebhook.js +7 -2
  82. package/dist/helpers/handleCreateIntegrationWebhook.js.map +1 -1
  83. package/dist/helpers/handleCreateLeaveRequestWebhook.d.ts +15 -0
  84. package/dist/helpers/handleCreateLeaveRequestWebhook.js +21 -0
  85. package/dist/helpers/handleCreateLeaveRequestWebhook.js.map +1 -0
  86. package/dist/helpers/handleDenyLeaveRequestWebhook.d.ts +15 -0
  87. package/dist/helpers/handleDenyLeaveRequestWebhook.js +21 -0
  88. package/dist/helpers/handleDenyLeaveRequestWebhook.js.map +1 -0
  89. package/dist/helpers/handleGetAuthorizationUrlWebhook.d.ts +4 -4
  90. package/dist/helpers/handleGetAuthorizationUrlWebhook.js +7 -2
  91. package/dist/helpers/handleGetAuthorizationUrlWebhook.js.map +1 -1
  92. package/dist/helpers/handleGetLeaveBalancesWebhook.d.ts +6 -7
  93. package/dist/helpers/handleGetLeaveBalancesWebhook.js +7 -2
  94. package/dist/helpers/handleGetLeaveBalancesWebhook.js.map +1 -1
  95. package/dist/helpers/handleGetLeaveCategoriesWebhook.d.ts +15 -0
  96. package/dist/helpers/handleGetLeaveCategoriesWebhook.js +27 -0
  97. package/dist/helpers/handleGetLeaveCategoriesWebhook.js.map +1 -0
  98. package/dist/helpers/handleGetLeaveRequestHoursWebhook.d.ts +13 -0
  99. package/dist/helpers/handleGetLeaveRequestHoursWebhook.js +27 -0
  100. package/dist/helpers/handleGetLeaveRequestHoursWebhook.js.map +1 -0
  101. package/dist/helpers/handleProcessLeaveRequestWebhook.d.ts +15 -0
  102. package/dist/helpers/handleProcessLeaveRequestWebhook.js +21 -0
  103. package/dist/helpers/handleProcessLeaveRequestWebhook.js.map +1 -0
  104. package/dist/helpers/handleRequest.d.ts +12 -0
  105. package/dist/helpers/handleRequest.js +58 -0
  106. package/dist/helpers/handleRequest.js.map +1 -0
  107. package/dist/helpers/handleRequestWithWorknice.d.ts +17 -8
  108. package/dist/helpers/handleRequestWithWorknice.js +35 -58
  109. package/dist/helpers/handleRequestWithWorknice.js.map +1 -1
  110. package/dist/helpers/handleTriggerIntegrationSyncWebhook.d.ts +16 -11
  111. package/dist/helpers/handleTriggerIntegrationSyncWebhook.js +223 -141
  112. package/dist/helpers/handleTriggerIntegrationSyncWebhook.js.map +1 -1
  113. package/dist/helpers/index.d.ts +9 -1
  114. package/dist/helpers/index.js +26 -10
  115. package/dist/helpers/index.js.map +1 -1
  116. package/dist/index.d.ts +9 -6
  117. package/dist/index.js +6 -8
  118. package/dist/index.js.map +1 -1
  119. package/dist/utils/isSamePlainDate.d.ts +3 -1
  120. package/dist/utils/isSamePlainDate.js +1 -1
  121. package/dist/utils/isSamePlainDate.js.map +1 -1
  122. package/dist/utils/isValidPlainDate.d.ts +1 -1
  123. package/dist/utils/isValidPlainDate.js +1 -1
  124. package/dist/utils/isValidPlainDate.js.map +1 -1
  125. package/dist/utils/parsePlainDate.d.ts +1 -1
  126. package/dist/utils/parsePlainDate.js +1 -1
  127. package/dist/utils/parsePlainDate.js.map +1 -1
  128. package/dist/webhooks.d.ts +71 -1
  129. package/package.json +4 -4
  130. package/dist/employee-records/validatePersonDataTransferLinePersonalDetails.d.ts +0 -6
  131. package/dist/employee-records/validatePersonDataTransferLinePersonalDetails.js +0 -38
  132. package/dist/employee-records/validatePersonDataTransferLinePersonalDetails.js.map +0 -1
  133. package/dist/utils/isAfter.d.ts +0 -4
  134. package/dist/utils/isAfter.js +0 -5
  135. package/dist/utils/isAfter.js.map +0 -1
@@ -1,11 +1,16 @@
1
+ import isInstantAfter from "@worknice/utils/temporal/isInstantAfter";
2
+ import isValidInstant from "@worknice/utils/temporal/isValidInstant";
1
3
  import { Temporal } from "temporal-polyfill";
2
4
  import { ConnectionStatus } from "../api/_types.js";
3
5
  import comparePersonDataTransferLines from "../employee-records/comparePersonDataTransferLines.js";
4
6
  import mergePersonDataTransferLines from "../employee-records/mergePersonDataTransferLines.js";
5
7
  import validatePersonDataTransferLineBankAccounts from "../employee-records/validatePersonDataTransferLineBankAccounts.js";
6
- import validatePersonDataTransferLinePersonalDetails from "../employee-records/validatePersonDataTransferLinePersonalDetails.js";
8
+ import validatePersonDataTransferLineDateOfBirth from "../employee-records/validatePersonDataTransferLineDateOfBirth.js";
9
+ import validatePersonDataTransferLineFullName from "../employee-records/validatePersonDataTransferLineFullName.js";
10
+ import validatePersonDataTransferLineGender from "../employee-records/validatePersonDataTransferLineGender.js";
11
+ import validatePersonDataTransferLinePersonalEmail from "../employee-records/validatePersonDataTransferLinePersonalEmail.js";
12
+ import validatePersonDataTransferLinePersonalPhone from "../employee-records/validatePersonDataTransferLinePersonalPhone.js";
7
13
  import validatePersonDataTransferLineResidentialAddress from "../employee-records/validatePersonDataTransferLineResidentialAddress.js";
8
- import isAfter from "../utils/isAfter.js";
9
14
  import handleRequestWithWorknice from "./handleRequestWithWorknice.js";
10
15
  const handleTriggerIntegrationSyncWebhook = async (request, {
11
16
  createRemotePerson,
@@ -18,9 +23,17 @@ const handleTriggerIntegrationSyncWebhook = async (request, {
18
23
  request,
19
24
  {
20
25
  getApiToken,
21
- getEnv,
22
26
  handleRequest: async (context) => {
23
27
  const { logger, payload, worknice } = context;
28
+ let cachedDataImport;
29
+ const getDataImport = async () => {
30
+ if (!cachedDataImport) {
31
+ cachedDataImport = await worknice.createDataImport({
32
+ integrationId: payload.integrationId
33
+ });
34
+ }
35
+ return cachedDataImport;
36
+ };
24
37
  try {
25
38
  logger.connect(worknice, payload.integrationId);
26
39
  logger.indent("Retrieving Worknice data\u2026");
@@ -60,7 +73,7 @@ const handleTriggerIntegrationSyncWebhook = async (request, {
60
73
  logger.dedent(`Completed retrieving ${config.appName} data.`);
61
74
  logger.indent("Updating person connections\u2026");
62
75
  for (const remotePerson of remotePeople) {
63
- const remotePersonName = `${remotePerson.personalDetails?.givenName} ${remotePerson.personalDetails?.familyName}`;
76
+ const remotePersonName = personToName(remotePerson);
64
77
  try {
65
78
  const remotePersonConnection = personConnections.find(
66
79
  (connection) => connection.remote?.id === remotePerson.metadata.sourceId
@@ -71,7 +84,7 @@ const handleTriggerIntegrationSyncWebhook = async (request, {
71
84
  personConnectionId: remotePersonConnection.id
72
85
  });
73
86
  logger.info(
74
- `Deleted connection for "${remotePerson.personalDetails?.givenName} ${remotePerson.personalDetails?.familyName}" in ${config.appName} because they have been terminated.`
87
+ `Deleted connection for "${remotePersonName}" in ${config.appName} because they have been terminated.`
75
88
  );
76
89
  }
77
90
  } else {
@@ -115,7 +128,7 @@ const handleTriggerIntegrationSyncWebhook = async (request, {
115
128
  );
116
129
  }
117
130
  const matchingWorknicePerson = people.find(
118
- (person) => person.employeeCode !== null && person.employeeCode === remotePerson.metadata.employeeCode || person.personalEmail !== null && person.personalEmail === remotePerson.personalDetails?.personalEmail || person.profileEmail !== null && person.profileEmail === remotePerson.profile?.profileEmail
131
+ (person) => person.id === remotePerson.metadata.targetId || person.employeeCode !== null && person.employeeCode === remotePerson.metadata.employeeCode || person.personalEmail !== null && person.personalEmail === remotePerson.personalEmail?.personalEmail || person.profileEmail !== null && person.profileEmail === remotePerson.profile?.profileEmail
119
132
  ) ?? null;
120
133
  if (config.automaticMatching === true && matchingWorknicePerson) {
121
134
  const personConnection = personConnections.find(
@@ -222,18 +235,13 @@ const handleTriggerIntegrationSyncWebhook = async (request, {
222
235
  }
223
236
  } catch (error) {
224
237
  logger.info(
225
- `Unable to update person connection for person "${remotePersonName}" in ${config.appName} because of the following error:
226
-
227
- ${error instanceof Error ? error.message : error}
228
- `
238
+ `Unable to update person connection for person "${remotePersonName}" in ${config.appName} because of the following error:`
229
239
  );
240
+ logger.error(error);
230
241
  }
231
242
  }
232
243
  logger.dedent("Finished updating person connections.");
233
244
  if (config.mode === "one-way" || config.mode === "two-way") {
234
- const dataImport = await worknice.createDataImport({
235
- integrationId: payload.integrationId
236
- });
237
245
  logger.indent("Updating people with connections marked as merged\u2026");
238
246
  const mergedConnections = personConnections.filter(
239
247
  (personConnection) => personConnection.status === ConnectionStatus.Merged
@@ -255,7 +263,7 @@ ${error instanceof Error ? error.message : error}
255
263
  `Unable to find person in ${config.appName} with the ID "${personConnection.remote.id}".`
256
264
  );
257
265
  }
258
- const remotePersonName = `${remotePerson.personalDetails?.givenName} ${remotePerson.personalDetails?.familyName}`;
266
+ const remotePersonName = personToName(remotePerson);
259
267
  const worknicePersonDataTransferLine = {
260
268
  ...worknicePersonToPersonDataTransferLine(worknicePerson),
261
269
  metadata: {
@@ -266,20 +274,29 @@ ${error instanceof Error ? error.message : error}
266
274
  updatedAt: worknicePerson.updatedAt
267
275
  },
268
276
  profile: {
277
+ displayName: worknicePerson.displayName,
269
278
  profileEmail: worknicePerson.profileEmail ?? null
270
279
  }
271
280
  };
272
- const myobPersonDataTransferLine = remotePerson;
281
+ const remotePersonDataTransferLine = remotePerson;
273
282
  const comparison = comparePersonDataTransferLines(
274
283
  worknicePersonDataTransferLine,
275
- myobPersonDataTransferLine
284
+ remotePersonDataTransferLine
276
285
  );
277
- if (comparison.hasDifferences && (comparison.sections.bankAccounts.hasDifferences || comparison.sections.personalDetails.hasDifferences || comparison.sections.residentialAddress.hasDifferences)) {
286
+ if (comparison.hasDifferences && (config.syncFields?.bankAccounts && comparison.sections.bankAccounts.hasDifferences || config.syncFields?.dateOfBirth && comparison.sections.dateOfBirth.hasDifferences || config.syncFields?.fullName && comparison.sections.fullName.hasDifferences || config.syncFields?.gender && comparison.sections.gender.hasDifferences || config.syncFields?.personalEmail && comparison.sections.personalEmail.hasDifferences || config.syncFields?.personalPhone && comparison.sections.personalPhone.hasDifferences || config.syncFields?.residentialAddress && comparison.sections.residentialAddress.hasDifferences)) {
278
287
  const worknicePersonUpdatedAt = Temporal.Instant.from(worknicePerson.updatedAt);
279
- const myobEmployeeUpdatedAt = Temporal.PlainDateTime.from(
288
+ if (!isValidInstant(remotePerson.metadata.updatedAt)) {
289
+ throw Error(
290
+ `Invalid updatedAt value for ${config.appName} person "${remotePersonName}". Must be in ISO 8601 format, including a date, a time, and a time zone offset.`,
291
+ {
292
+ cause: Error(`Unable to parse: ${remotePerson.metadata.updatedAt}`)
293
+ }
294
+ );
295
+ }
296
+ const remotePersonUpdatedAt = Temporal.Instant.from(
280
297
  remotePerson.metadata.updatedAt
281
- ).toZonedDateTime(Temporal.TimeZone.from("UTC")).toInstant();
282
- if (isAfter(worknicePersonUpdatedAt, myobEmployeeUpdatedAt)) {
298
+ );
299
+ if (isInstantAfter(worknicePersonUpdatedAt, remotePersonUpdatedAt)) {
283
300
  if (config.mode === "two-way") {
284
301
  if (!updateRemotePerson) {
285
302
  throw Error(
@@ -294,31 +311,46 @@ ${error instanceof Error ? error.message : error}
294
311
  logger.info(`Updated person "${remotePersonName}" in ${config.appName}.`);
295
312
  } catch (error) {
296
313
  logger.info(
297
- `Unable to update person "${remotePersonName}" in ${config.appName} because of the following error:
298
-
299
- ${error instanceof Error ? error.message : error}
300
- `
314
+ `Unable to update person "${remotePersonName}" in ${config.appName} because of the following error:`
301
315
  );
316
+ logger.error(error);
302
317
  }
303
318
  }
304
319
  } else {
305
320
  try {
306
- const personalDetails = validatePersonDataTransferLinePersonalDetails(
307
- myobPersonDataTransferLine.personalDetails
308
- );
309
321
  const bankAccounts = validatePersonDataTransferLineBankAccounts(
310
- myobPersonDataTransferLine.bankAccounts
322
+ remotePersonDataTransferLine.bankAccounts
323
+ );
324
+ const dateOfBirth = validatePersonDataTransferLineDateOfBirth(
325
+ remotePersonDataTransferLine.dateOfBirth
326
+ );
327
+ const fullName = validatePersonDataTransferLineFullName(
328
+ remotePersonDataTransferLine.fullName
329
+ );
330
+ const gender = validatePersonDataTransferLineGender(
331
+ remotePersonDataTransferLine.gender
332
+ );
333
+ const personalEmail = validatePersonDataTransferLinePersonalEmail(
334
+ remotePersonDataTransferLine.personalEmail
335
+ );
336
+ const personalPhone = validatePersonDataTransferLinePersonalPhone(
337
+ remotePersonDataTransferLine.personalPhone
311
338
  );
312
339
  const residentialAddress = validatePersonDataTransferLineResidentialAddress(
313
- myobPersonDataTransferLine.residentialAddress
340
+ remotePersonDataTransferLine.residentialAddress
314
341
  );
342
+ const dataImport = await getDataImport();
315
343
  await worknice.createPersonDataImportLine({
316
344
  bankAccounts,
317
345
  config: {
318
346
  bankAccounts: config.syncFields?.bankAccounts ?? false,
347
+ dateOfBirth: config.syncFields?.dateOfBirth ?? false,
319
348
  emergencyContacts: config.syncFields?.emergencyContacts ?? false,
320
- personalDetails: config.syncFields?.personalDetails ?? false,
321
- postalAddress: config.syncFields?.personalDetails ?? false,
349
+ fullName: config.syncFields?.fullName ?? false,
350
+ gender: config.syncFields?.gender ?? false,
351
+ personalEmail: config.syncFields?.personalEmail ?? false,
352
+ personalPhone: config.syncFields?.personalPhone ?? false,
353
+ postalAddress: config.syncFields?.postalAddress ?? false,
322
354
  profile: config.syncFields?.profile ?? false,
323
355
  remuneration: config.syncFields?.remuneration ?? false,
324
356
  residentialAddress: config.syncFields?.residentialAddress ?? false,
@@ -327,8 +359,12 @@ ${error instanceof Error ? error.message : error}
327
359
  tenure: config.syncFields?.tenure ?? false
328
360
  },
329
361
  dataImportId: dataImport.id,
362
+ dateOfBirth,
330
363
  emergencyContacts: null,
331
- personalDetails,
364
+ fullName,
365
+ gender,
366
+ personalEmail,
367
+ personalPhone,
332
368
  personId: worknicePerson.id,
333
369
  postalAddress: null,
334
370
  residentialAddress,
@@ -342,70 +378,93 @@ ${error instanceof Error ? error.message : error}
342
378
  logger.info(`Updated person "${worknicePerson.displayName}" in Worknice.`);
343
379
  } catch (error) {
344
380
  logger.info(
345
- `Unable to update person "${worknicePerson.displayName}" in Worknice because of the following error:
346
-
347
- ${error instanceof Error ? error.message : error}
348
- `
381
+ `Unable to update person "${worknicePerson.displayName}" in Worknice because of the following error:`
349
382
  );
383
+ logger.error(error);
350
384
  }
351
385
  }
352
386
  }
353
387
  }
354
388
  logger.dedent("Finished updating people with connections marked as merged.");
355
- logger.indent("Merging unmerged connections\u2026");
356
- const connectedConnections = personConnections.filter(
357
- (personConnection) => personConnection.status === ConnectionStatus.Connected
389
+ }
390
+ logger.indent("Merging unmerged connections\u2026");
391
+ const connectedConnections = personConnections.filter(
392
+ (personConnection) => personConnection.status === ConnectionStatus.Connected
393
+ );
394
+ for (const personConnection of connectedConnections) {
395
+ const worknicePerson = people.find(
396
+ (person) => person.id === personConnection.person.id
358
397
  );
359
- for (const personConnection of connectedConnections) {
360
- const worknicePerson = people.find(
361
- (person) => person.id === personConnection.person.id
362
- );
363
- const remotePerson = remotePeople.find(
364
- (person) => person.metadata.sourceId === personConnection.remote.id
398
+ const remotePerson = remotePeople.find(
399
+ (person) => person.metadata.sourceId === personConnection.remote.id
400
+ );
401
+ if (!worknicePerson) {
402
+ throw Error(
403
+ `Unable to find person in Worknice with the ID "${personConnection.person.id}".`
365
404
  );
366
- if (!worknicePerson) {
367
- throw Error(
368
- `Unable to find person in Worknice with the ID "${personConnection.person.id}".`
369
- );
370
- }
371
- if (!remotePerson) {
372
- throw Error(
373
- `Unable to find person in ${config.appName} with the ID "${personConnection.remote.id}".`
374
- );
375
- }
376
- const remotePersonName = `${remotePerson.personalDetails?.givenName} ${remotePerson.personalDetails?.familyName}`;
377
- logger.indent(
378
- `Merging Worknice person "${worknicePerson.displayName}" with ${config.appName} person "${remotePersonName}"\u2026`
405
+ }
406
+ if (!remotePerson) {
407
+ throw Error(
408
+ `Unable to find person in ${config.appName} with the ID "${personConnection.remote.id}".`
379
409
  );
380
- try {
410
+ }
411
+ const remotePersonName = personToName(remotePerson);
412
+ logger.indent(
413
+ `Merging Worknice person "${worknicePerson.displayName}" with ${config.appName} person "${remotePersonName}"\u2026`
414
+ );
415
+ try {
416
+ if (config.mode === "one-way" || config.mode === "two-way") {
381
417
  const worknicePersonUpdatedAt = Temporal.Instant.from(worknicePerson.updatedAt);
382
- const myobEmployeeUpdatedAt = Temporal.PlainDateTime.from(
418
+ if (!isValidInstant(remotePerson.metadata.updatedAt)) {
419
+ throw Error(
420
+ `Invalid updatedAt value for ${config.appName} person "${remotePersonName}". Must be in ISO 8601 format, including a date, a time, and a time zone offset.`,
421
+ {
422
+ cause: Error(`Unable to parse: ${remotePerson.metadata.updatedAt}`)
423
+ }
424
+ );
425
+ }
426
+ const remotePersonUpdatedAt = Temporal.Instant.from(
383
427
  remotePerson.metadata.updatedAt
384
- ).toZonedDateTime(Temporal.TimeZone.from("UTC")).toInstant();
385
- const [primaryDataTransferLine, secondaryDataTransferLine] = isAfter(
428
+ );
429
+ const [primaryDataTransferLine, secondaryDataTransferLine] = isInstantAfter(
386
430
  worknicePersonUpdatedAt,
387
- myobEmployeeUpdatedAt
431
+ remotePersonUpdatedAt
388
432
  ) ? [worknicePersonToPersonDataTransferLine(worknicePerson), remotePerson] : [remotePerson, worknicePersonToPersonDataTransferLine(worknicePerson)];
389
433
  const mergedDataTransferLine = mergePersonDataTransferLines(
390
434
  primaryDataTransferLine,
391
435
  secondaryDataTransferLine
392
436
  );
393
- const personalDetails = validatePersonDataTransferLinePersonalDetails(
394
- mergedDataTransferLine.personalDetails
395
- );
396
437
  const bankAccounts = validatePersonDataTransferLineBankAccounts(
397
438
  mergedDataTransferLine.bankAccounts
398
439
  );
440
+ const dateOfBirth = validatePersonDataTransferLineDateOfBirth(
441
+ mergedDataTransferLine.dateOfBirth
442
+ );
443
+ const fullName = validatePersonDataTransferLineFullName(
444
+ mergedDataTransferLine.fullName
445
+ );
446
+ const gender = validatePersonDataTransferLineGender(mergedDataTransferLine.gender);
447
+ const personalEmail = validatePersonDataTransferLinePersonalEmail(
448
+ mergedDataTransferLine.personalEmail
449
+ );
450
+ const personalPhone = validatePersonDataTransferLinePersonalPhone(
451
+ mergedDataTransferLine.personalPhone
452
+ );
399
453
  const residentialAddress = validatePersonDataTransferLineResidentialAddress(
400
454
  mergedDataTransferLine.residentialAddress
401
455
  );
456
+ const dataImport = await getDataImport();
402
457
  await worknice.createPersonDataImportLine({
403
458
  bankAccounts,
404
459
  config: {
405
460
  bankAccounts: config.syncFields?.bankAccounts ?? false,
461
+ dateOfBirth: config.syncFields?.dateOfBirth ?? false,
406
462
  emergencyContacts: config.syncFields?.emergencyContacts ?? false,
407
- personalDetails: config.syncFields?.personalDetails ?? false,
408
- postalAddress: config.syncFields?.personalDetails ?? false,
463
+ fullName: config.syncFields?.fullName ?? false,
464
+ gender: config.syncFields?.gender ?? false,
465
+ personalEmail: config.syncFields?.personalEmail ?? false,
466
+ personalPhone: config.syncFields?.personalPhone ?? false,
467
+ postalAddress: config.syncFields?.postalAddress ?? false,
409
468
  profile: config.syncFields?.profile ?? false,
410
469
  remuneration: config.syncFields?.remuneration ?? false,
411
470
  residentialAddress: config.syncFields?.residentialAddress ?? false,
@@ -414,8 +473,12 @@ ${error instanceof Error ? error.message : error}
414
473
  tenure: config.syncFields?.tenure ?? false
415
474
  },
416
475
  dataImportId: dataImport.id,
476
+ dateOfBirth,
417
477
  emergencyContacts: null,
418
- personalDetails,
478
+ fullName,
479
+ gender,
480
+ personalEmail,
481
+ personalPhone,
419
482
  personId: worknicePerson.id,
420
483
  postalAddress: null,
421
484
  residentialAddress,
@@ -444,6 +507,7 @@ ${error instanceof Error ? error.message : error}
444
507
  updatedAt: worknicePerson.updatedAt
445
508
  },
446
509
  profile: {
510
+ displayName: worknicePerson.displayName,
447
511
  profileEmail: worknicePerson.profileEmail ?? null
448
512
  }
449
513
  },
@@ -451,81 +515,78 @@ ${error instanceof Error ? error.message : error}
451
515
  );
452
516
  logger.info(`Updated person "${remotePersonName}" in ${config.appName}.`);
453
517
  }
454
- await worknice.updatePersonConnection({
455
- personConnectionId: personConnection.id,
456
- personId: personConnection.person.id,
457
- remote: {
458
- id: remotePerson.metadata.sourceId,
459
- name: remotePersonName
460
- },
461
- status: ConnectionStatus.Merged
462
- });
463
- logger.dedent(`Finished merging.`);
464
- } catch (error) {
465
- logger.info(
466
- `Unable to merge ${config.appName} person "${remotePersonName}" and Worknice person "${worknicePerson.displayName}" because of the following error:
467
-
468
- ${error instanceof Error ? error.message : error}
469
- `
470
- );
471
- logger.dedent();
472
518
  }
519
+ await worknice.updatePersonConnection({
520
+ personConnectionId: personConnection.id,
521
+ personId: personConnection.person.id,
522
+ remote: {
523
+ id: remotePerson.metadata.sourceId,
524
+ name: remotePersonName
525
+ },
526
+ status: ConnectionStatus.Merged
527
+ });
528
+ logger.dedent(`Finished merging.`);
529
+ } catch (error) {
530
+ logger.info(
531
+ `Unable to merge ${config.appName} person "${remotePersonName}" and Worknice person "${worknicePerson.displayName}" because of the following error:`
532
+ );
533
+ logger.error(error);
534
+ logger.dedent();
473
535
  }
474
- logger.dedent("Finished merging unmerged connections.");
475
- if (config.mode === "two-way") {
476
- logger.indent(`Adding new people to ${config.appName}\u2026`);
477
- const localOnlyConnections = personConnections.filter(
478
- (personConnection) => personConnection.status === ConnectionStatus.LocalOnly
536
+ }
537
+ logger.dedent("Finished merging unmerged connections.");
538
+ if (config.mode === "two-way") {
539
+ logger.indent(`Adding new people to ${config.appName}\u2026`);
540
+ const localOnlyConnections = personConnections.filter(
541
+ (personConnection) => personConnection.status === ConnectionStatus.LocalOnly
542
+ );
543
+ for (const personConnection of localOnlyConnections) {
544
+ const worknicePerson = people.find(
545
+ (person) => person.id === personConnection.person.id
479
546
  );
480
- for (const personConnection of localOnlyConnections) {
481
- const worknicePerson = people.find(
482
- (person) => person.id === personConnection.person.id
547
+ if (!worknicePerson) {
548
+ throw Error(
549
+ `Unable to find person in Worknice with the ID "${personConnection.person.id}".`
483
550
  );
484
- if (!worknicePerson) {
551
+ }
552
+ try {
553
+ if (!createRemotePerson) {
485
554
  throw Error(
486
- `Unable to find person in Worknice with the ID "${personConnection.person.id}".`
555
+ "No createRemotePerson function supplied to handleTriggerIntegrationSyncWebhook."
487
556
  );
488
557
  }
489
- try {
490
- if (!createRemotePerson) {
491
- throw Error(
492
- "No createRemotePerson function supplied to handleTriggerIntegrationSyncWebhook."
493
- );
494
- }
495
- const remote = await createRemotePerson(
496
- {
497
- ...worknicePersonToPersonDataTransferLine(worknicePerson),
498
- metadata: {
499
- deleted: false,
500
- employeeCode: worknicePerson.employeeCode ?? null,
501
- sourceId: worknicePerson.id,
502
- targetId: null,
503
- updatedAt: worknicePerson.updatedAt
504
- },
505
- profile: {
506
- profileEmail: worknicePerson.profileEmail ?? null
507
- }
558
+ const remote = await createRemotePerson(
559
+ {
560
+ ...worknicePersonToPersonDataTransferLine(worknicePerson),
561
+ metadata: {
562
+ deleted: false,
563
+ employeeCode: worknicePerson.employeeCode ?? null,
564
+ sourceId: worknicePerson.id,
565
+ targetId: null,
566
+ updatedAt: worknicePerson.updatedAt
508
567
  },
509
- contextWithIntegration
510
- );
511
- await worknice.updatePersonConnection({
512
- personConnectionId: personConnection.id,
513
- personId: personConnection.person.id,
514
- remote,
515
- status: ConnectionStatus.Merged
516
- });
517
- logger.info(`Added new person "${remote.name}" to ${config.appName}.`);
518
- } catch (error) {
519
- logger.info(
520
- `Unable to add person "${worknicePerson.displayName}" in Worknice to ${config.appName} because of the following error:
521
-
522
- ${error instanceof Error ? error.message : error}
523
- `
524
- );
525
- }
568
+ profile: {
569
+ displayName: worknicePerson.displayName,
570
+ profileEmail: worknicePerson.profileEmail ?? null
571
+ }
572
+ },
573
+ contextWithIntegration
574
+ );
575
+ await worknice.updatePersonConnection({
576
+ personConnectionId: personConnection.id,
577
+ personId: personConnection.person.id,
578
+ remote,
579
+ status: ConnectionStatus.Merged
580
+ });
581
+ logger.info(`Added new person "${remote.name}" to ${config.appName}.`);
582
+ } catch (error) {
583
+ logger.info(
584
+ `Unable to add person "${worknicePerson.displayName}" in Worknice to ${config.appName} because of the following error:`
585
+ );
586
+ logger.error(error);
526
587
  }
527
- logger.dedent(`Finished adding new people to ${config.appName}.`);
528
588
  }
589
+ logger.dedent(`Finished adding new people to ${config.appName}.`);
529
590
  }
530
591
  await worknice.completeSync({ integrationId: payload.integrationId });
531
592
  logger.info("Sync completed.");
@@ -534,10 +595,25 @@ ${error instanceof Error ? error.message : error}
534
595
  throw error;
535
596
  }
536
597
  },
537
- parsePayload: async ({ request: request2 }) => request2.json()
598
+ parseRequest: async (context) => {
599
+ const payload = await context.request.json();
600
+ return {
601
+ env: await getEnv({ ...context, payload }),
602
+ payload
603
+ };
604
+ }
538
605
  },
539
606
  options
540
607
  );
608
+ const personToName = (person) => {
609
+ if ((person.fullName?.givenName ?? "").trim() !== "" && (person.fullName?.familyName ?? "").trim() !== "") {
610
+ return `${person.fullName?.givenName} ${person.fullName?.familyName}`;
611
+ }
612
+ if ((person.profile?.displayName ?? "").trim() !== "") {
613
+ return `${person.profile?.displayName}`;
614
+ }
615
+ return `(unnamed person ${person.metadata.sourceId})`;
616
+ };
541
617
  const worknicePersonToPersonDataTransferLine = (worknicePerson) => ({
542
618
  bankAccounts: worknicePerson.bankAccount1AllocationMethod ? {
543
619
  bankAccount1Allocation: worknicePerson.bankAccount1Allocation ?? null,
@@ -566,15 +642,21 @@ const worknicePersonToPersonDataTransferLine = (worknicePerson) => ({
566
642
  bankAccount5Name: worknicePerson.bankAccount5Name ?? null,
567
643
  bankAccount5Number: worknicePerson.bankAccount5Number ?? null
568
644
  } : null,
645
+ dateOfBirth: worknicePerson.dateOfBirth ? { dateOfBirth: worknicePerson.dateOfBirth } : null,
569
646
  emergencyContacts: null,
570
- personalDetails: worknicePerson.givenName ? {
571
- dateOfBirth: worknicePerson.dateOfBirth ?? null,
647
+ fullName: worknicePerson.givenName ? {
572
648
  familyName: worknicePerson.familyName ?? null,
573
- gender: worknicePerson.gender ?? null,
574
649
  givenName: worknicePerson.givenName ?? null,
575
- otherGivenNames: worknicePerson.otherGivenNames ?? null,
576
- personalEmail: worknicePerson.personalEmail ?? null,
577
- personalPhone: worknicePerson.personalPhone ?? null
650
+ otherGivenNames: worknicePerson.otherGivenNames ?? null
651
+ } : null,
652
+ gender: worknicePerson.gender ? {
653
+ gender: worknicePerson.gender
654
+ } : null,
655
+ personalEmail: worknicePerson.personalEmail ? {
656
+ personalEmail: worknicePerson.personalEmail
657
+ } : null,
658
+ personalPhone: worknicePerson.personalPhone ? {
659
+ personalPhone: worknicePerson.personalPhone
578
660
  } : null,
579
661
  postalAddress: null,
580
662
  residentialAddress: worknicePerson.residentialAddressLine1 ? {