@plusscommunities/pluss-maintenance-aws 2.1.44 → 2.1.46

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 (45) hide show
  1. package/createJob.js +201 -114
  2. package/createJobType.js +49 -49
  3. package/db/maintenance/addMaintenanceJob.js +100 -90
  4. package/db/maintenance/editMaintenanceJob.js +22 -12
  5. package/db/maintenance/getJobEmail.js +22 -22
  6. package/deleteJob.js +58 -58
  7. package/deleteJobType.js +40 -40
  8. package/editJob.js +126 -65
  9. package/editJobStatus.js +57 -57
  10. package/editJobType.js +61 -61
  11. package/editNote.js +117 -117
  12. package/feature.config.js +279 -262
  13. package/getData.js +48 -41
  14. package/getJob.js +4 -4
  15. package/getJobType.js +35 -35
  16. package/getJobTypes.js +66 -66
  17. package/getJobs.js +48 -48
  18. package/integration/IntegrationStrategy.js +52 -52
  19. package/integration/archibus/ArchibusStrategy.js +42 -28
  20. package/integration/index.js +19 -19
  21. package/jobChanged.js +88 -89
  22. package/jobTypesChanged.js +52 -39
  23. package/package.json +3 -3
  24. package/requests/assignRequest.js +81 -81
  25. package/requests/getAssignees.js +27 -27
  26. package/requests/getExternalSync.js +100 -100
  27. package/requests/getPropertyRequests.js +89 -0
  28. package/requests/getRequest.js +77 -77
  29. package/requests/getRequests.js +210 -144
  30. package/requests/helper/hasRequestPermission.js +12 -12
  31. package/requests/helper/isValidAssignee.js +10 -10
  32. package/requests/retrySync.js +90 -90
  33. package/requests/setExternalJobId.js +113 -113
  34. package/requests/updatePriority.js +33 -33
  35. package/scheduleJobImport.js +63 -63
  36. package/sendJobEmail.js +105 -104
  37. package/updateData.js +34 -34
  38. package/values.config.a.js +26 -25
  39. package/values.config.default.js +30 -28
  40. package/values.config.enquiry.js +222 -221
  41. package/values.config.feedback.js +194 -193
  42. package/values.config.food.js +29 -28
  43. package/values.config.forms.js +29 -28
  44. package/values.config.js +30 -28
  45. package/watchJobs.js +154 -154
package/getJob.js CHANGED
@@ -5,10 +5,10 @@ const generateJsonResponse = require("@plusscommunities/pluss-core-aws/helper/ge
5
5
  const getRequest = require("./requests/getRequest");
6
6
 
7
7
  module.exports.getJob = async (event, context, callback) => {
8
- init(config);
9
- const data = getBody(event);
8
+ init(config);
9
+ const data = getBody(event);
10
10
 
11
- const result = await getRequest(event, data);
11
+ const result = await getRequest(event, data);
12
12
 
13
- return callback(null, generateJsonResponse(result.status, result.data));
13
+ return callback(null, generateJsonResponse(result.status, result.data));
14
14
  };
package/getJobType.js CHANGED
@@ -7,41 +7,41 @@ const validateSiteAccess = require("@plusscommunities/pluss-core-aws/helper/auth
7
7
  const { values } = require("./values.config");
8
8
 
9
9
  module.exports.getJobType = (event, context, callback) => {
10
- init(config);
11
- const data = getBody(event);
10
+ init(config);
11
+ const data = getBody(event);
12
12
 
13
- if (!data.site || !data.typeId) {
14
- return callback(
15
- null,
16
- generateJsonResponse(422, {
17
- error: { message: "User Types fetch -- no site or type id detected." },
18
- })
19
- );
20
- }
13
+ if (!data.site || !data.typeId) {
14
+ return callback(
15
+ null,
16
+ generateJsonResponse(422, {
17
+ error: { message: "User Types fetch -- no site or type id detected." },
18
+ }),
19
+ );
20
+ }
21
21
 
22
- validateSiteAccess(event, data.site)
23
- .then((authorised) => {
24
- if (!authorised) {
25
- return callback(
26
- null,
27
- generateJsonResponse(422, { fail: true, error: "not authorised" })
28
- );
29
- }
30
- getRef(values.tableNameJobTypes, "id", data.typeId)
31
- .then((gweg) => {
32
- return callback(null, generateJsonResponse(200, gweg));
33
- })
34
- .catch((error) => {
35
- return callback(
36
- null,
37
- generateJsonResponse(200, {
38
- userFetchFail: true,
39
- message: "Fail on user query. Please try again.",
40
- })
41
- );
42
- });
43
- })
44
- .catch((error) => {
45
- callback(null, generateJsonResponse(422, { fail: true, error }));
46
- });
22
+ validateSiteAccess(event, data.site)
23
+ .then((authorised) => {
24
+ if (!authorised) {
25
+ return callback(
26
+ null,
27
+ generateJsonResponse(422, { fail: true, error: "not authorised" }),
28
+ );
29
+ }
30
+ getRef(values.tableNameJobTypes, "id", data.typeId)
31
+ .then((gweg) => {
32
+ return callback(null, generateJsonResponse(200, gweg));
33
+ })
34
+ .catch((error) => {
35
+ return callback(
36
+ null,
37
+ generateJsonResponse(200, {
38
+ userFetchFail: true,
39
+ message: "Fail on user query. Please try again.",
40
+ }),
41
+ );
42
+ });
43
+ })
44
+ .catch((error) => {
45
+ callback(null, generateJsonResponse(422, { fail: true, error }));
46
+ });
47
47
  };
package/getJobTypes.js CHANGED
@@ -10,76 +10,76 @@ const createGuid = require("@plusscommunities/pluss-core-aws/helper/createGuid")
10
10
  const { values } = require("./values.config");
11
11
 
12
12
  module.exports.getJobTypes = (event, context, callback) => {
13
- init(config);
14
- const data = getBody(event);
13
+ init(config);
14
+ const data = getBody(event);
15
15
 
16
- if (!data.site) {
17
- return callback(
18
- null,
19
- generateJsonResponse(422, {
20
- error: { message: "User Types fetch -- no site detected." },
21
- })
22
- );
23
- }
24
- validateSiteAccess(event, data.site)
25
- .then((authorised) => {
26
- if (!authorised) {
27
- return callback(
28
- null,
29
- generateJsonResponse(422, { fail: true, error: "not authorised" })
30
- );
31
- }
16
+ if (!data.site) {
17
+ return callback(
18
+ null,
19
+ generateJsonResponse(422, {
20
+ error: { message: "User Types fetch -- no site detected." },
21
+ }),
22
+ );
23
+ }
24
+ validateSiteAccess(event, data.site)
25
+ .then((authorised) => {
26
+ if (!authorised) {
27
+ return callback(
28
+ null,
29
+ generateJsonResponse(422, { fail: true, error: "not authorised" }),
30
+ );
31
+ }
32
32
 
33
- const query = {
34
- IndexName: "JobTypeSiteIndex",
35
- KeyConditionExpression: "site = :site",
36
- ExpressionAttributeValues: {
37
- ":site": data.site,
38
- },
39
- };
33
+ const query = {
34
+ IndexName: "JobTypeSiteIndex",
35
+ KeyConditionExpression: "site = :site",
36
+ ExpressionAttributeValues: {
37
+ ":site": data.site,
38
+ },
39
+ };
40
40
 
41
- indexQuery(values.tableNameJobTypes, query)
42
- .then(async (typeRes) => {
43
- if (!_.isEmpty(typeRes.Items)) {
44
- return callback(null, generateJsonResponse(200, typeRes.Items));
45
- }
41
+ indexQuery(values.tableNameJobTypes, query)
42
+ .then(async (typeRes) => {
43
+ if (!_.isEmpty(typeRes.Items)) {
44
+ return callback(null, generateJsonResponse(200, typeRes.Items));
45
+ }
46
46
 
47
- const defaultJobTypes = [];
48
- if (values.allowGeneralType) {
49
- const generalType = {
50
- id: createGuid().substring(0, 8),
51
- typeName: "General",
52
- site: data.site,
53
- };
47
+ const defaultJobTypes = [];
48
+ if (values.allowGeneralType) {
49
+ const generalType = {
50
+ id: createGuid().substring(0, 8),
51
+ typeName: "General",
52
+ site: data.site,
53
+ };
54
54
 
55
- await updateRef(values.tableNameJobTypes, generalType);
56
- defaultJobTypes.push(generalType);
57
- }
58
- if (values.defaultJobTypes?.length) {
59
- for await (const jobType of values.defaultJobTypes) {
60
- const defaultType = {
61
- ...jobType,
62
- id: createGuid().substring(0, 8),
63
- site: data.site,
64
- };
65
- await updateRef(values.tableNameJobTypes, defaultType);
66
- defaultJobTypes.push(defaultType);
67
- }
68
- }
55
+ await updateRef(values.tableNameJobTypes, generalType);
56
+ defaultJobTypes.push(generalType);
57
+ }
58
+ if (values.defaultJobTypes?.length) {
59
+ for await (const jobType of values.defaultJobTypes) {
60
+ const defaultType = {
61
+ ...jobType,
62
+ id: createGuid().substring(0, 8),
63
+ site: data.site,
64
+ };
65
+ await updateRef(values.tableNameJobTypes, defaultType);
66
+ defaultJobTypes.push(defaultType);
67
+ }
68
+ }
69
69
 
70
- return callback(null, generateJsonResponse(200, defaultJobTypes));
71
- })
72
- .catch((error) => {
73
- return callback(
74
- null,
75
- generateJsonResponse(200, {
76
- userFetchFail: true,
77
- message: "Fail on user query. Please try again.",
78
- })
79
- );
80
- });
81
- })
82
- .catch((error) => {
83
- callback(null, generateJsonResponse(422, { fail: true, error }));
84
- });
70
+ return callback(null, generateJsonResponse(200, defaultJobTypes));
71
+ })
72
+ .catch((error) => {
73
+ return callback(
74
+ null,
75
+ generateJsonResponse(200, {
76
+ userFetchFail: true,
77
+ message: "Fail on user query. Please try again.",
78
+ }),
79
+ );
80
+ });
81
+ })
82
+ .catch((error) => {
83
+ callback(null, generateJsonResponse(422, { fail: true, error }));
84
+ });
85
85
  };
package/getJobs.js CHANGED
@@ -8,56 +8,56 @@ const getSessionUser = require("@plusscommunities/pluss-core-aws/helper/auth/get
8
8
  const { values } = require("./values.config");
9
9
 
10
10
  module.exports.getJobs = async (event, context, callback) => {
11
- init(config);
12
- const data = getBody(event);
11
+ init(config);
12
+ const data = getBody(event);
13
13
 
14
- if (!data.site) {
15
- return callback(
16
- null,
17
- generateJsonResponse(422, {
18
- error: { message: "User Types fetch -- no site detected." },
19
- })
20
- );
21
- }
14
+ if (!data.site) {
15
+ return callback(
16
+ null,
17
+ generateJsonResponse(422, {
18
+ error: { message: "User Types fetch -- no site detected." },
19
+ }),
20
+ );
21
+ }
22
22
 
23
- try {
24
- const authorised = await validateMasterAuth(
25
- event,
26
- values.permissionMaintenanceTracking
27
- );
28
- const userId = authorised
29
- ? null
30
- : await getSessionUser(event.headers.authkey);
31
- console.log("getting jobs for user", userId);
23
+ try {
24
+ const authorised = await validateMasterAuth(
25
+ event,
26
+ values.permissionMaintenanceTracking,
27
+ );
28
+ const userId = authorised
29
+ ? null
30
+ : await getSessionUser(event.headers.authkey);
31
+ console.log("getting jobs for user", userId);
32
32
 
33
- const query = {
34
- IndexName: "MaintenanceSiteIndex",
35
- KeyConditionExpression: "site = :site",
36
- ExpressionAttributeValues: {
37
- ":site": data.site,
38
- },
39
- };
33
+ const query = {
34
+ IndexName: "MaintenanceSiteIndex",
35
+ KeyConditionExpression: "site = :site",
36
+ ExpressionAttributeValues: {
37
+ ":site": data.site,
38
+ },
39
+ };
40
40
 
41
- try {
42
- const res = await indexQuery(values.tableNameMaintenance, query);
43
- let jobs = userId
44
- ? res.Items.filter((job) => job.userID === userId)
45
- : res.Items;
46
- if (data.status)
47
- jobs = jobs.filter((j) => data.status.includes(j.status));
48
- if (data.type) jobs = jobs.filter((j) => data.type.includes(j.type));
49
- console.log("jobs count", jobs?.length);
50
- return callback(null, generateJsonResponse(200, jobs));
51
- } catch (error1) {
52
- return callback(
53
- null,
54
- generateJsonResponse(200, {
55
- userFetchFail: true,
56
- message: "Fail on user query. Please try again.",
57
- })
58
- );
59
- }
60
- } catch (error) {
61
- callback(null, generateJsonResponse(422, { fail: true, error }));
62
- }
41
+ try {
42
+ const res = await indexQuery(values.tableNameMaintenance, query);
43
+ let jobs = userId
44
+ ? res.Items.filter((job) => job.userID === userId)
45
+ : res.Items;
46
+ if (data.status)
47
+ jobs = jobs.filter((j) => data.status.includes(j.status));
48
+ if (data.type) jobs = jobs.filter((j) => data.type.includes(j.type));
49
+ console.log("jobs count", jobs?.length);
50
+ return callback(null, generateJsonResponse(200, jobs));
51
+ } catch (error1) {
52
+ return callback(
53
+ null,
54
+ generateJsonResponse(200, {
55
+ userFetchFail: true,
56
+ message: "Fail on user query. Please try again.",
57
+ }),
58
+ );
59
+ }
60
+ } catch (error) {
61
+ callback(null, generateJsonResponse(422, { fail: true, error }));
62
+ }
63
63
  };
@@ -1,56 +1,56 @@
1
1
  class IntegrationStrategy {
2
- getEntityType = () => {
3
- return "maintenance_null";
4
- };
5
-
6
- isValidIntegration = () => {
7
- return false;
8
- };
9
-
10
- getRefreshInterval = () => {
11
- return 15 * 60 * 1000; // 15 minutes
12
- };
13
-
14
- // creates a request on the integrated system
15
- createRequest = async (request) => {
16
- return null;
17
- };
18
-
19
- // gets a request from the integrated system
20
- getRequest = async (requestId) => {
21
- return null;
22
- };
23
-
24
- // refreshed a request from the integrated system
25
- refreshFromSource = async (requestId) => {
26
- return null;
27
- };
28
-
29
- // actions taken when a request's status has changed
30
- onStatusChanged = async (request) => {
31
- return null;
32
- };
33
-
34
- // actions taken when a comment has been added to a request
35
- onCommentAdded = async (request) => {
36
- return null;
37
- };
38
-
39
- // actions taken when a note has been added to a request
40
- onNotesAdded = async (request) => {
41
- return null;
42
- };
43
-
44
- // actions taken when a request is marked as completed
45
- onCompleteRequest = async (request) => {
46
- return null;
47
- };
48
-
49
- // TODO: Remove once all existing records have ActiveEntityType (PC-1382)
50
- // backfills ActiveEntityType on existing externalentities records for the sparse GSI migration
51
- backfillActiveEntityType = async (timeout) => {
52
- return { backfillCount: 0, complete: true };
53
- };
2
+ getEntityType = () => {
3
+ return "maintenance_null";
4
+ };
5
+
6
+ isValidIntegration = () => {
7
+ return false;
8
+ };
9
+
10
+ getRefreshInterval = () => {
11
+ return 15 * 60 * 1000; // 15 minutes
12
+ };
13
+
14
+ // creates a request on the integrated system
15
+ createRequest = async (request) => {
16
+ return null;
17
+ };
18
+
19
+ // gets a request from the integrated system
20
+ getRequest = async (requestId) => {
21
+ return null;
22
+ };
23
+
24
+ // refreshed a request from the integrated system
25
+ refreshFromSource = async (requestId) => {
26
+ return null;
27
+ };
28
+
29
+ // actions taken when a request's status has changed
30
+ onStatusChanged = async (request) => {
31
+ return null;
32
+ };
33
+
34
+ // actions taken when a comment has been added to a request
35
+ onCommentAdded = async (request) => {
36
+ return null;
37
+ };
38
+
39
+ // actions taken when a note has been added to a request
40
+ onNotesAdded = async (request) => {
41
+ return null;
42
+ };
43
+
44
+ // actions taken when a request is marked as completed
45
+ onCompleteRequest = async (request) => {
46
+ return null;
47
+ };
48
+
49
+ // TODO: Remove once all existing records have ActiveEntityType (PC-1382)
50
+ // backfills ActiveEntityType on existing externalentities records for the sparse GSI migration
51
+ backfillActiveEntityType = async (timeout) => {
52
+ return { backfillCount: 0, complete: true };
53
+ };
54
54
  }
55
55
 
56
56
  module.exports = IntegrationStrategy;
@@ -62,6 +62,33 @@ class ArchibusStrategy extends IntegrationStrategy {
62
62
  * @param {Object} mockResponse - Mock response from Archibus to simulate response
63
63
  * @returns {Boolean} Whether the request was created on Archibus
64
64
  */
65
+ recordCreateFailure = async (request, logId, reason) => {
66
+ try {
67
+ const failedJob = await getRef(
68
+ values.tableNameMaintenance,
69
+ "id",
70
+ request.id,
71
+ );
72
+ if (!failedJob.history) failedJob.history = [];
73
+ failedJob.history.push({
74
+ timestamp: moment.utc().valueOf(),
75
+ EntryType: "ExternalIDSetFailed",
76
+ reason,
77
+ user: {
78
+ displayName: "Archibus Integration",
79
+ id: "system",
80
+ },
81
+ systemType: "Archibus",
82
+ });
83
+
84
+ await editRef(values.tableNameMaintenance, "id", request.id, {
85
+ history: failedJob.history,
86
+ });
87
+ } catch (historyError) {
88
+ log("Archibus:CreateRequest", "HistoryError", historyError, logId);
89
+ }
90
+ };
91
+
65
92
  createRequest = async (request, mockResponse = null) => {
66
93
  const logId = log("Archibus:CreateRequest", "Start", request);
67
94
 
@@ -84,7 +111,16 @@ class ArchibusStrategy extends IntegrationStrategy {
84
111
  if (building?.SiteCode) siteId = building.SiteCode.toString();
85
112
  buildingCode = building?.BuildingCode;
86
113
  }
87
- if (!siteId) return false;
114
+ if (!siteId) {
115
+ log(
116
+ "Archibus:CreateRequest",
117
+ "MissingSiteId",
118
+ { site: request.site, room: request.room },
119
+ logId,
120
+ );
121
+ await this.recordCreateFailure(request, logId, "Missing site_id mapping");
122
+ return false;
123
+ }
88
124
 
89
125
  try {
90
126
  const data = {
@@ -111,7 +147,7 @@ class ArchibusStrategy extends IntegrationStrategy {
111
147
  (await axios({
112
148
  method: "PUT",
113
149
  url: `${this.baseUrl}/createWorkRequest`,
114
- timeout: 30000,
150
+ timeout: 120000,
115
151
  headers: {
116
152
  [this.apiKeyHeader]: this.apiKey,
117
153
  "Content-Type": "application/json",
@@ -171,29 +207,7 @@ class ArchibusStrategy extends IntegrationStrategy {
171
207
  log("Archibus:CreateRequest", "Error", e, logId);
172
208
 
173
209
  // Add history entry for failed integration
174
- try {
175
- const failedJob = await getRef(
176
- values.tableNameMaintenance,
177
- "id",
178
- request.id,
179
- );
180
- if (!failedJob.history) failedJob.history = [];
181
- failedJob.history.push({
182
- timestamp: moment.utc().valueOf(),
183
- EntryType: "ExternalIDSetFailed",
184
- user: {
185
- displayName: "Archibus Integration",
186
- id: "system",
187
- },
188
- systemType: "Archibus",
189
- });
190
-
191
- await editRef(values.tableNameMaintenance, "id", request.id, {
192
- history: failedJob.history,
193
- });
194
- } catch (historyError) {
195
- log("Archibus:CreateRequest", "HistoryError", historyError, logId);
196
- }
210
+ await this.recordCreateFailure(request, logId, e.message);
197
211
  }
198
212
  return false;
199
213
  };
@@ -210,7 +224,7 @@ class ArchibusStrategy extends IntegrationStrategy {
210
224
  const response = await axios({
211
225
  method: "GET",
212
226
  url: `${this.baseUrl}/getWorkRequest/${externalId}`,
213
- timeout: 30000,
227
+ timeout: 120000,
214
228
  headers: {
215
229
  [this.apiKeyHeader]: this.apiKey,
216
230
  "Content-Type": "application/json",
@@ -386,7 +400,7 @@ class ArchibusStrategy extends IntegrationStrategy {
386
400
  method: "POST",
387
401
  url: `${this.baseUrl}/addCommentsToWRSteps`,
388
402
  data: postData,
389
- timeout: 30000,
403
+ timeout: 120000,
390
404
  headers: {
391
405
  [this.apiKeyHeader]: this.apiKey,
392
406
  "Content-Type": "application/json",
@@ -455,7 +469,7 @@ class ArchibusStrategy extends IntegrationStrategy {
455
469
  method: "POST",
456
470
  url: `${this.baseUrl}/addDocumentToWorkRequest`,
457
471
  data: postData,
458
- timeout: 60000,
472
+ timeout: 120000,
459
473
  headers: {
460
474
  [this.apiKeyHeader]: this.apiKey,
461
475
  "Content-Type": "application/json",
@@ -6,25 +6,25 @@ const IntegrationStrategy = require("./IntegrationStrategy");
6
6
  const { values } = require("../values.config");
7
7
 
8
8
  exports.getStrategy = async (site) => {
9
- let importConfig;
10
- const logId = log("getStrategy", "Site", site);
11
- try {
12
- importConfig = await getString(
13
- getRowId(site, `${values.serviceKey}integration`),
14
- "plussSpace"
15
- );
9
+ let importConfig;
10
+ const logId = log("getStrategy", "Site", site);
11
+ try {
12
+ importConfig = await getString(
13
+ getRowId(site, `${values.serviceKey}integration`),
14
+ "plussSpace",
15
+ );
16
16
 
17
- switch (importConfig.Strategy) {
18
- case "Archibus":
19
- return new ArchibusStrategy(importConfig);
20
- case "SeeStuff":
21
- return new SeeStuffStrategy(importConfig);
22
- default:
23
- return new IntegrationStrategy();
24
- }
25
- } catch (e) {
26
- log("getStrategy", "Error", e, logId);
27
- }
17
+ switch (importConfig.Strategy) {
18
+ case "Archibus":
19
+ return new ArchibusStrategy(importConfig);
20
+ case "SeeStuff":
21
+ return new SeeStuffStrategy(importConfig);
22
+ default:
23
+ return new IntegrationStrategy();
24
+ }
25
+ } catch (e) {
26
+ log("getStrategy", "Error", e, logId);
27
+ }
28
28
 
29
- return new IntegrationStrategy();
29
+ return new IntegrationStrategy();
30
30
  };