@getjones/test-infra 2.6.7 → 2.7.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.
Files changed (42) hide show
  1. package/package.json +1 -1
  2. package/src/common/commonFlows/auth/auth.js +40 -0
  3. package/src/common/commonFlows/index.js +2 -1
  4. package/src/common/commonFlows/records/records.js +1 -0
  5. package/src/common/consts/dashboardCharts.js +17 -0
  6. package/src/common/utils/complianceUtil.js +56 -0
  7. package/src/common/utils/timeUtils.js +2 -1
  8. package/src/defaults/configs/coverage.js +227 -0
  9. package/src/defaults/configs/polices.js +2 -1
  10. package/src/defaults/index.js +2 -1
  11. package/src/factory/records/records.js +2 -2
  12. package/src/index.js +6 -0
  13. package/src/saas/internal-api/accounts/models/settings/update.settings.model.js +10 -1
  14. package/src/saas/internal-api/auditNotes/api/audit.notes.api.js +40 -0
  15. package/src/saas/internal-api/auditNotes/api/audit.notes.service.js +115 -0
  16. package/src/saas/internal-api/auditNotes/index.js +4 -0
  17. package/src/saas/internal-api/auditNotes/models/audit.note.model.js +30 -0
  18. package/src/saas/internal-api/auth/api/auth.api.js +14 -5
  19. package/src/saas/internal-api/auth/api/auth.service.js +21 -5
  20. package/src/saas/internal-api/compliance/api/audit/audit.service.js +18 -32
  21. package/src/saas/internal-api/compliance/api/coverage/coverage.service.js +25 -1
  22. package/src/saas/internal-api/compliance/api/waive/waive.service.js +5 -5
  23. package/src/saas/internal-api/compliance/utils/{util.js → auditUtil.js} +0 -9
  24. package/src/saas/internal-api/compliance/utils/coverageUtil.js +40 -0
  25. package/src/saas/internal-api/contractors/api/contractors.api.js +7 -1
  26. package/src/saas/internal-api/contractors/api/contractors.service.js +12 -1
  27. package/src/saas/internal-api/contractors/consts/consts.js +6 -0
  28. package/src/saas/internal-api/contractors/index.js +2 -1
  29. package/src/saas/internal-api/contractors/models/assign.requirement.model.js +10 -0
  30. package/src/saas/internal-api/dbEmails/consts/consts.js +33 -1
  31. package/src/saas/internal-api/dbEmails/index.js +2 -1
  32. package/src/saas/internal-api/dbEmails/utils/util.js +10 -1
  33. package/src/saas/internal-api/projects/utils/utils.js +1 -1
  34. package/src/saas/internal-api/requests/api/requests.api.js +14 -2
  35. package/src/saas/internal-api/requests/api/requests.service.js +26 -1
  36. package/src/saas/internal-api/requests/models/create.request.model.js +5 -1
  37. package/src/saas/internal-api/requestsTable/api/requests.table.api.js +20 -0
  38. package/src/saas/internal-api/requestsTable/api/requests.table.service.js +14 -0
  39. package/src/saas/internal-api/requestsTable/index.js +3 -0
  40. package/src/saas/internal-api/requirements/api/requirements.service.js +16 -14
  41. package/src/saas/internal-api/requirements/models/update.requirement.model.js +3 -2
  42. package/src/saas/internal-api/requirements/utils/utils.js +2 -2
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@getjones/test-infra",
3
- "version": "2.6.7",
3
+ "version": "2.7.0",
4
4
  "description": "Providing internal and openapi interface",
5
5
  "main": "src/index.js",
6
6
  "scripts": {
@@ -0,0 +1,40 @@
1
+ const { expect } = require('chai');
2
+
3
+ const env = require('../../../../../../src/env');
4
+
5
+ const { internalAPI } = require('../../../../src')(env);
6
+ const { dbEmails, auth } = internalAPI;
7
+
8
+ const httpResponseStatusCodes = require('../../../common/httpResponseStatusCodes.json');
9
+
10
+ const textInSubject = 'One-Time Security Code';
11
+ const textInBody = 'Please use the one-time code below to confirm your identity';
12
+ const codeLength = 6;
13
+
14
+ const getVendorHubAuthCookie = async email => {
15
+ const createOneTimeSessionResponse = await auth.services.createOneTimeSession(email);
16
+ expect(createOneTimeSessionResponse.status, `Create one-time session for email ${email} has failed`).to.equal(httpResponseStatusCodes.OK);
17
+
18
+ const recipients = {
19
+ from: env.credentials.superUser,
20
+ to: [email]
21
+ };
22
+
23
+ const userEmailBody = await dbEmails.services.getLastMessage({ recipients, textInSubject });
24
+ expect(userEmailBody, 'Fetching user one-time security code email has failed').to.be.a('string').that.includes(textInBody);
25
+
26
+ const oneTimeCode = await extractOneTimeCode(userEmailBody);
27
+ expect(oneTimeCode.length, 'One-time security code extraction from email body has failed').to.equal(codeLength);
28
+
29
+ return auth.services.getHubUserCookie(email, oneTimeCode);
30
+ };
31
+
32
+ async function extractOneTimeCode(inputString) {
33
+ const regex = '\s*(\\d{6})\n\s*';
34
+ const match = inputString.match(regex);
35
+
36
+ return match ? match[1] : null;
37
+ }
38
+ module.exports = {
39
+ getVendorHubAuthCookie
40
+ };
@@ -1,3 +1,4 @@
1
1
  const records = require('./records/records');
2
+ const auth = require('./auth/auth');
2
3
 
3
- module.exports = { records };
4
+ module.exports = { records, auth };
@@ -16,6 +16,7 @@ const makeRecordNotResponsive = async function(recordId, context, { isTenant } =
16
16
  };
17
17
 
18
18
  const updateInviteDate = async function(recordId, inviteDate, context) {
19
+ await timeUtils.waitFor(1).seconds;
19
20
  const updateResponse = await contractors.services.updateInviteDate(recordId, inviteDate, context);
20
21
 
21
22
  if (updateResponse.status !== httpResponseStatusCodes.NO_CONTENT) {
@@ -0,0 +1,17 @@
1
+ const chartTypes = {
2
+ requiringAttention: 'requiringAttention',
3
+ expirationDatePerMonth: 'expirationDatePerMonth',
4
+ waivedByRequirement: 'waivedByRequirement'
5
+ };
6
+ const sortBy = {
7
+ companyName: 'SORT_BY_COMPANYNAME',
8
+ projectName: 'SORT_BY_PROJECT_NAME',
9
+ insuranceStatus: 'SORT_BY_INSURANCE_STATUS',
10
+ minPolicyExpiration: 'SORT_BY_MIN_POLICY_EXP'
11
+
12
+ };
13
+
14
+ module.exports = {
15
+ chartTypes,
16
+ sortBy
17
+ };
@@ -0,0 +1,56 @@
1
+ const { getEnv, getSystemUserIdentity } = require('../../env');
2
+ const { credentials } = getEnv();
3
+
4
+ const auditApi = require('../../saas/internal-api/compliance/api/audit/audit.api');
5
+
6
+ const isReaudit = (contractorId, context) => {
7
+ return auditApi.isReaudit(contractorId, context);
8
+ };
9
+
10
+ const getAuditorId = () => {
11
+ const auditorIdentity = getSystemUserIdentity(credentials.auditorUser);
12
+ return auditorIdentity.id;
13
+ };
14
+
15
+ const getAuditMetadata = async (
16
+ auditorContext,
17
+ accountId,
18
+ projectId,
19
+ requirementId,
20
+ recordId,
21
+ {
22
+ isProjectOnboarding = false,
23
+ shouldSendNotificationToPM = false
24
+ } = {}) => {
25
+ const metadata = {
26
+ accountId,
27
+ projectId,
28
+ requirementId,
29
+ contractorId: recordId,
30
+ isProjectOnboarding,
31
+ shouldSendNotificationToPM
32
+ };
33
+
34
+ const isReauditResponse = await isReaudit(recordId, auditorContext);
35
+ metadata.isReaudit = isReauditResponse.data.isReaudit;
36
+
37
+ const recordDetailsResponse = await auditApi.getContractorDetailsForAudit(recordId, auditorContext);
38
+ const { vendorDetails } = recordDetailsResponse.data;
39
+
40
+ metadata.certificateId = vendorDetails.certificateDetails.certificateuploadId;
41
+ metadata.auditDates = {
42
+ contractorId: recordId,
43
+ contractorDateModified: vendorDetails.dateModified,
44
+ dateStartedAudit: recordDetailsResponse.dateStartedAudit,
45
+ contractorOverrideDateModified: vendorDetails.contractorOverrideDateModified,
46
+ contractCreateDate: vendorDetails.contractCreateDate
47
+ };
48
+
49
+ metadata.auditorId = await getAuditorId();
50
+
51
+ return metadata;
52
+ };
53
+
54
+ module.exports = {
55
+ getAuditMetadata
56
+ };
@@ -13,7 +13,8 @@ const formats = {
13
13
  threadScheduler: '', // Passing empty string resolves moment.js format to ISO8601 standard like 2020-04-12T09:49:59Z;
14
14
  monthDayYear12hTime: 'MMM D, YYYY h:mm A',
15
15
  amPmTime: 'h:mm A',
16
- yearMonthDay: 'YYYY-MM-DD'
16
+ yearMonthDay: 'YYYY-MM-DD',
17
+ shortedMonthName: 'MMM'
17
18
  };
18
19
 
19
20
  const peroids = {
@@ -0,0 +1,227 @@
1
+ const policies = require('../configs/polices');
2
+
3
+ const defaultExpiryDate = '2030-10-10T00:00:00.000Z';
4
+ const defaultEffectiveDate = '2020-10-10T00:00:00.000Z';
5
+
6
+ const policiesConfig = {
7
+ [policies.policyNames.generalLiability]: {
8
+ key: 'generalLiability',
9
+ policyEntities: [
10
+ {
11
+ effectiveDate: defaultEffectiveDate,
12
+ expiryDate: defaultExpiryDate,
13
+ policyNumber: 'GL-12345'
14
+ }
15
+ ],
16
+ limits: [
17
+ {
18
+ key: 'eachOccurrence',
19
+ value: 1000000
20
+ },
21
+ {
22
+ key: 'productsCompletedOperationsAggregate',
23
+ value: 3000000
24
+ },
25
+ {
26
+ key: 'personalAdvertisingInjury',
27
+ value: 1000000
28
+ },
29
+ {
30
+ key: 'medicalExpenses',
31
+ value: 5000
32
+ },
33
+ {
34
+ key: 'damageToRentedPremises',
35
+ value: 50000
36
+ },
37
+ {
38
+ key: 'generalAggregate',
39
+ value: 2000000
40
+ }
41
+ ],
42
+ provisions: [
43
+ {
44
+ key: 'primaryNonContributoryProvision',
45
+ value: true
46
+ },
47
+ {
48
+ key: 'primaryNonContributoryForAdditionalInsured',
49
+ value: true
50
+ },
51
+ {
52
+ key: '10DaysNoticeOfCancellation',
53
+ value: true
54
+ },
55
+ {
56
+ key: 'contractualLiability',
57
+ value: true
58
+ },
59
+ {
60
+ key: 'perOccur',
61
+ value: true
62
+ },
63
+ {
64
+ key: 'perPolicy',
65
+ value: true
66
+ },
67
+ {
68
+ key: 'perProject',
69
+ value: true
70
+ }
71
+ ]
72
+ },
73
+ [policies.policyNames.automobileLiability]: {
74
+ key: 'automobileLiability',
75
+ policyEntities: [
76
+ {
77
+ effectiveDate: defaultEffectiveDate,
78
+ expiryDate: defaultExpiryDate,
79
+ policyNumber: 'AL-12345'
80
+ }
81
+ ],
82
+ limits: [
83
+ {
84
+ key: 'combinedSingleLimit',
85
+ value: 1000000
86
+ }
87
+ ],
88
+ provisions: [
89
+ {
90
+ key: 'anyAuto',
91
+ value: true
92
+ },
93
+ {
94
+ key: 'waiverOfSubrogation',
95
+ value: true
96
+ },
97
+ {
98
+ key: 'hired',
99
+ value: true
100
+ }
101
+ ]
102
+ },
103
+ [policies.policyNames.excessLiability]: {
104
+ key: 'excessLiability',
105
+ policyEntities: [
106
+ {
107
+ effectiveDate: defaultEffectiveDate,
108
+ expiryDate: defaultExpiryDate,
109
+ policyNumber: 'EL-12345'
110
+ }
111
+ ],
112
+ limits: [
113
+ {
114
+ key: 'eachOccurrence',
115
+ value: 1000000
116
+ }
117
+ ],
118
+ provisions: [
119
+ {
120
+ key: 'occur',
121
+ value: true
122
+ }
123
+ ]
124
+ },
125
+ [policies.policyNames.umbrella]: {
126
+ key: 'umbrellaLiability',
127
+ policyEntities: [
128
+ {
129
+ effectiveDate: defaultEffectiveDate,
130
+ expiryDate: defaultExpiryDate,
131
+ policyNumber: 'Um-12345'
132
+ }
133
+ ],
134
+ limits: [
135
+ {
136
+ key: 'eachOccurrence',
137
+ value: 5000000
138
+ },
139
+ {
140
+ key: 'aggregate',
141
+ value: 5000000
142
+ }
143
+ ],
144
+ provisions: [
145
+ {
146
+ key: 'occur',
147
+ value: true
148
+ }
149
+ ]
150
+ },
151
+ [policies.policyNames.workersCompensation]: {
152
+ key: 'workersCompensation',
153
+ policyEntities: [
154
+ {
155
+ effectiveDate: defaultEffectiveDate,
156
+ expiryDate: defaultExpiryDate,
157
+ policyNumber: 'WC-12345'
158
+ }
159
+ ],
160
+ limits: [
161
+ {
162
+ key: 'employersLiabilityEachAccident',
163
+ value: 1000000
164
+ },
165
+ {
166
+ key: 'employersLiabilityDiseaseEachEmployee',
167
+ value: 1000000
168
+ }
169
+ ],
170
+ provisions: [
171
+ {
172
+ key: 'statutoryLimitsRequired',
173
+ value: true
174
+ }
175
+ ]
176
+ },
177
+ [policies.policyNames.fidelityCrime]: {
178
+ key: 'fidelityCrime',
179
+ policyEntities: [
180
+ {
181
+ effectiveDate: defaultEffectiveDate,
182
+ expiryDate: defaultExpiryDate,
183
+ policyNumber: 'FC-12345'
184
+ }
185
+ ],
186
+ limits: [
187
+ {
188
+ key: 'clientProperty',
189
+ value: 1000000
190
+ }
191
+ ],
192
+ provisions: [
193
+ ]
194
+ },
195
+ [policies.policyNames.cyberLiability]: {
196
+ key: 'cyberLiability',
197
+ policyEntities: [
198
+ {
199
+ effectiveDate: defaultEffectiveDate,
200
+ expiryDate: defaultExpiryDate,
201
+ policyNumber: 'CL-12345'
202
+ }
203
+ ],
204
+ limits: [
205
+ {
206
+ key: 'eachClaim',
207
+ value: 1000000
208
+ }
209
+ ],
210
+ provisions: [
211
+ ]
212
+ }
213
+ };
214
+
215
+ const getAllAvailablePolicies = () => Object.keys(policiesConfig);
216
+
217
+ const getRequiredPoliciesMinimumForAutocomplete = () => {
218
+ const policies = getAllAvailablePolicies();
219
+ policies.length = 2;
220
+ return policies;
221
+ };
222
+
223
+ module.exports = {
224
+ getAllAvailablePolicies,
225
+ getRequiredPoliciesMinimumForAutocomplete,
226
+ policiesConfig
227
+ };
@@ -39,7 +39,8 @@ const attributeNames = {
39
39
  cancellationTerms: 'Cancellation Terms',
40
40
  coiAuthentication: 'COI authentication',
41
41
  signature: 'Signature',
42
- occur: 'Occur'
42
+ occur: 'Occur',
43
+ text: 'text'
43
44
  };
44
45
 
45
46
  module.exports = {
@@ -1,5 +1,6 @@
1
1
  const audit = require('./configs/auditConfigs');
2
2
  const polices = require('./configs/polices');
3
3
  const requirement = require('./configs/requirement');
4
+ const coverage = require('./configs/coverage');
4
5
 
5
- module.exports = { audit, polices, requirement };
6
+ module.exports = { audit, polices, requirement, coverage };
@@ -87,7 +87,7 @@ const prepareRecord = async (recordCompany, recordEmail, status, tabId, requirem
87
87
  } while (auditResponse.status !== httpResponseStatusCodes.NO_CONTENT && retries--);
88
88
 
89
89
  if (auditResponse.status !== httpResponseStatusCodes.NO_CONTENT) {
90
- throw Error(`Failed to audit record ${record.company}\n${auditResponse}`);
90
+ throw Error(`Failed to audit record ${recordCompany}\n${auditResponse}`);
91
91
  }
92
92
 
93
93
  return recordId;
@@ -112,7 +112,7 @@ const prepareAboutToExpiredRecord = (recordCompany, recordEmail, tabId, requirem
112
112
  const prepareWaivedRecord = async (recordCompany, recordEmail, tabId, requirementId, context) => {
113
113
  const recordId = await prepareRecord(recordCompany, recordEmail, complianceStatuses.notCompliant, tabId, requirementId, context);
114
114
 
115
- const record = await contractors.services.getContractorById(recordId, context);
115
+ const { data: record } = await contractors.services.getContractorById(recordId, context);
116
116
  await compliance.services.waive.waiveAll(record, context);
117
117
 
118
118
  return recordId;
package/src/index.js CHANGED
@@ -22,6 +22,8 @@ const getInternalAPI = () => {
22
22
 
23
23
  const coi = require('./saas/internal-api/coi');
24
24
  const compliance = require('./saas/internal-api/compliance');
25
+ const auditNotes = require('./saas/internal-api/auditNotes');
26
+
25
27
  const users = require('./saas/internal-api/users');
26
28
 
27
29
  const reports = require('./saas/internal-api/reports');
@@ -32,6 +34,8 @@ const getInternalAPI = () => {
32
34
  const vendorProfile = require('./saas/internal-api/vendorProfile');
33
35
  const serviceArea = require('./saas/internal-api/serviceArea');
34
36
 
37
+ const requestsTable = require('./saas/internal-api/requestsTable');
38
+
35
39
  const threadScheduler = require('./saas/internal-api/thread-scheduler/runner');
36
40
  const dbEmails = require('./saas/internal-api/dbEmails/index');
37
41
 
@@ -46,6 +50,7 @@ const getInternalAPI = () => {
46
50
  requests,
47
51
  coi,
48
52
  compliance,
53
+ auditNotes,
49
54
  reports,
50
55
  users,
51
56
  charts,
@@ -53,6 +58,7 @@ const getInternalAPI = () => {
53
58
  globalRecord,
54
59
  vendorProfile,
55
60
  serviceArea,
61
+ requestsTable,
56
62
  threadScheduler,
57
63
  dbEmails,
58
64
  factory
@@ -8,7 +8,9 @@ class UpdateAccountSettingsModel {
8
8
  isExcludedFromNetwork = false,
9
9
  isOcrEnabled = false,
10
10
  isCoverageAudit = false,
11
- isAccountRequirementsEnabled = false
11
+ isAccountRequirementsEnabled = false,
12
+ isAccountRequirementsAutoRenewalsEnabled = false,
13
+ autoGaps = {}
12
14
  } = {}
13
15
  ) {
14
16
  this.accountId = accountId;
@@ -19,7 +21,14 @@ class UpdateAccountSettingsModel {
19
21
  this.isOcrEnabled = isOcrEnabled;
20
22
  this.isCoverageAudit = isCoverageAudit;
21
23
  this.isAccountRequirementsEnabled = isAccountRequirementsEnabled;
24
+ this.isAccountRequirementsAutoRenewalsEnabled = isAccountRequirementsAutoRenewalsEnabled;
25
+ this.autoGaps = { ... DEFAULT_AUTO_GAPS, ... autoGaps };
22
26
  }
23
27
  }
24
28
 
29
+ const DEFAULT_AUTO_GAPS = {
30
+ isAutoGapsEnabledForTenants: false,
31
+ isAutoGapsEnabledForVendors: false
32
+ };
33
+
25
34
  module.exports = UpdateAccountSettingsModel;
@@ -0,0 +1,40 @@
1
+ const requests = require('../../../../common/requests/cookieAuth/requests');
2
+ const { backendUrl } = require('../../../../env').getEnv();
3
+
4
+ const saas_notes_path = 'saas/notes';
5
+ const Endpoints = {
6
+ saasNotes: `${backendUrl}/${saas_notes_path}`,
7
+ getNotesForAuditor: `${backendUrl}/${saas_notes_path}/auditor`,
8
+ updateNote: `${backendUrl}/${saas_notes_path}/update`,
9
+ deleteNote: noteId => `${backendUrl}/${saas_notes_path}/${noteId}`
10
+ };
11
+
12
+ const createAuditNote = (noteModel, context) => {
13
+ return requests.postRequestHandler(Endpoints.saasNotes, noteModel, context);
14
+ };
15
+
16
+ const getAuditNotesByProjectId = (projectId, context) => {
17
+ const params = { projectId };
18
+ return requests.getRequestHandler(Endpoints.saasNotes, params, context);
19
+ };
20
+
21
+ const getAuditNotesByRecordId = (recordId, context) => {
22
+ const params = { contractorId: recordId };
23
+ return requests.getRequestHandler(Endpoints.getNotesForAuditor, params, context);
24
+ };
25
+
26
+ const updateAuditNote = (noteModel, context) => {
27
+ return requests.postRequestHandler(Endpoints.updateNote, noteModel, context);
28
+ };
29
+
30
+ const deleteAuditNoteById = (noteId, context) => {
31
+ return requests.deleteRequestHandler(Endpoints.deleteNote(noteId), context);
32
+ };
33
+
34
+ module.exports = {
35
+ createAuditNote,
36
+ getAuditNotesByProjectId,
37
+ getAuditNotesByRecordId,
38
+ updateAuditNote,
39
+ deleteAuditNoteById
40
+ };
@@ -0,0 +1,115 @@
1
+ const auditApi = require('./audit.notes.api');
2
+ const { AuditNoteModel } = require('../models/audit.note.model');
3
+ const { validateType } = require('../../../../common/validations/typeValidations');
4
+ const httpResponseStatusCodes = require('../../../../common/httpResponseStatusCodes.json');
5
+
6
+ const createAuditNote = async (auditNoteModel, context) => {
7
+ validateType(auditNoteModel, AuditNoteModel);
8
+ const response = await auditApi.createAuditNote(auditNoteModel, context);
9
+
10
+ if (response.status !== httpResponseStatusCodes.NO_CONTENT) {
11
+ throw Error(`Failed to create audit note - Response: ${response.status}`);
12
+ }
13
+
14
+ return response;
15
+ };
16
+
17
+ const getAuditNotesByProjectId = async (projectId, context) => {
18
+ const response = await auditApi.getAuditNotesByProjectId(projectId, context);
19
+
20
+ if (response.status !== httpResponseStatusCodes.OK) {
21
+ throw Error(`Failed to get audit notes by project id: ${projectId} - Response: ${response.status}`);
22
+ }
23
+
24
+ return response.data;
25
+ };
26
+
27
+ const getAuditNotesByRecordId = async (recordId, context) => {
28
+ const response = await auditApi.getAuditNotesByRecordId(recordId, context);
29
+
30
+ if (response.status !== httpResponseStatusCodes.OK) {
31
+ throw Error(`Failed to get audit notes by record id: ${recordId} - Response: ${response.status}`);
32
+ }
33
+
34
+ return response.data;
35
+ };
36
+
37
+ const updateAuditNote = async (auditNoteModel, context) => {
38
+ validateType(auditNoteModel, AuditNoteModel);
39
+ const response = await auditApi.updateAuditNote(auditNoteModel, context);
40
+
41
+ if (response.status !== httpResponseStatusCodes.NO_CONTENT) {
42
+ throw Error(`Failed to update audit note - Response: ${response.status}`);
43
+ }
44
+
45
+ return response;
46
+ };
47
+
48
+ const deleteAuditNoteById = (noteId, context) => {
49
+ return auditApi.deleteAuditNoteById(noteId, context);
50
+ };
51
+
52
+ const deleteAllAuditNotesInProject = async (projectId, context) => {
53
+ const existingAuditNotes = await getAuditNotesByProjectId(projectId, context);
54
+
55
+ for (const auditNotesType in existingAuditNotes) {
56
+ if (existingAuditNotes[auditNotesType] && existingAuditNotes[auditNotesType].length) {
57
+ await deleteAuditNotesByIds(existingAuditNotes[auditNotesType], context);
58
+ }
59
+ }
60
+ };
61
+
62
+ const deleteAllAccountLevelNotes = async (projectId, context) => { //does not delete all notes in account, only account level notes!
63
+ const existingAuditNotes = await getAuditNotesByProjectId(projectId, context);
64
+ const accountLevelNotesArr = existingAuditNotes.Account;
65
+
66
+ if (accountLevelNotesArr.length) {
67
+ await deleteAuditNotesByIds(accountLevelNotesArr, context);
68
+ }
69
+ };
70
+
71
+ const deleteAllProjectLevelNotes = async (projectId, context) => { //does not delete all notes in project, only project level notes!
72
+ const existingAuditNotes = await getAuditNotesByProjectId(projectId, context);
73
+ const projectLevelNotesArr = existingAuditNotes.Project;
74
+
75
+ if (projectLevelNotesArr.length) {
76
+ await deleteAuditNotesByIds(projectLevelNotesArr, context);
77
+ }
78
+ };
79
+
80
+ const deleteAllRequirementLevelNotes = async (projectId, context) => {
81
+ const existingAuditNotes = await getAuditNotesByProjectId(projectId, context);
82
+ const requirementLevelNotesArr = existingAuditNotes.Requirement;
83
+
84
+ if (requirementLevelNotesArr.length) {
85
+ await deleteAuditNotesByIds(requirementLevelNotesArr, context);
86
+ }
87
+ };
88
+
89
+ module.exports = {
90
+ createAuditNote,
91
+ getAuditNotesByProjectId,
92
+ getAuditNotesByRecordId,
93
+ updateAuditNote,
94
+ deleteAuditNoteById,
95
+ deleteAllAccountLevelNotes,
96
+ deleteAllProjectLevelNotes,
97
+ deleteAllRequirementLevelNotes,
98
+ deleteAllAuditNotesInProject
99
+ };
100
+
101
+ async function deleteAuditNotesByIds(notes, context) {
102
+ const failed = [];
103
+ for (const note of notes) {
104
+ const deleteNoteResponse = await deleteAuditNoteById(note.id, context);
105
+
106
+ if (deleteNoteResponse.status !== httpResponseStatusCodes.NO_CONTENT) { //see what EP of delete is returning when all goes well - maybe need to change !status
107
+ console.error('Failed to delete note: ', note.id);
108
+ failed.push(deleteNoteResponse);
109
+ }
110
+ }
111
+
112
+ if (failed.length) {
113
+ throw Error(`Failed to delete ${failed.length} of ${existingAuditNotes.length} records in account. Failed with status: ${ failed[0].status }`);
114
+ }
115
+ }
@@ -0,0 +1,4 @@
1
+ const services = require('./api/audit.notes.service');
2
+ const models = require('./models/audit.note.model');
3
+
4
+ module.exports = { services, models };
@@ -0,0 +1,30 @@
1
+ class AuditNoteModel {
2
+ constructor(noteEntityType, entityId, note, { id, gapQuote, requirementName } = {}) {
3
+ validateNoteEntityType(noteEntityType);
4
+
5
+ this.noteEntityType = noteEntityType;
6
+ this.entityId = entityId;
7
+ this.note = note;
8
+
9
+ this.id = id;
10
+ this.gapQuote = gapQuote;
11
+ this.requirementName = requirementName;
12
+ }
13
+ }
14
+
15
+ const auditNoteTypes = {
16
+ account: 'Account',
17
+ project: 'Project',
18
+ requirement: 'Requirement'
19
+ };
20
+
21
+ module.exports = {
22
+ AuditNoteModel,
23
+ auditNoteTypes
24
+ };
25
+
26
+ const validateNoteEntityType = noteEntityType => {
27
+ if (![auditNoteTypes.account, auditNoteTypes.project, auditNoteTypes.requirement].includes(noteEntityType)) {
28
+ throw new Error(`Invalid noteEntityType: ${noteEntityType}`);
29
+ }
30
+ };