@getjones/test-infra 2.6.8 → 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.
- package/package.json +1 -1
- package/src/common/commonFlows/records/records.js +1 -0
- package/src/common/consts/dashboardCharts.js +17 -0
- package/src/common/utils/complianceUtil.js +56 -0
- package/src/common/utils/timeUtils.js +2 -1
- package/src/defaults/configs/coverage.js +227 -0
- package/src/defaults/configs/polices.js +2 -1
- package/src/defaults/index.js +2 -1
- package/src/factory/records/records.js +2 -2
- package/src/index.js +3 -0
- package/src/saas/internal-api/auditNotes/api/audit.notes.api.js +40 -0
- package/src/saas/internal-api/auditNotes/api/audit.notes.service.js +115 -0
- package/src/saas/internal-api/auditNotes/index.js +4 -0
- package/src/saas/internal-api/auditNotes/models/audit.note.model.js +30 -0
- package/src/saas/internal-api/compliance/api/audit/audit.service.js +18 -32
- package/src/saas/internal-api/compliance/api/coverage/coverage.service.js +25 -1
- package/src/saas/internal-api/compliance/api/waive/waive.service.js +5 -5
- package/src/saas/internal-api/compliance/utils/{util.js → auditUtil.js} +0 -9
- package/src/saas/internal-api/compliance/utils/coverageUtil.js +40 -0
- package/src/saas/internal-api/contractors/api/contractors.api.js +7 -1
- package/src/saas/internal-api/contractors/api/contractors.service.js +12 -1
- package/src/saas/internal-api/contractors/index.js +2 -1
- package/src/saas/internal-api/contractors/models/assign.requirement.model.js +10 -0
- package/src/saas/internal-api/dbEmails/consts/consts.js +33 -1
- package/src/saas/internal-api/dbEmails/index.js +2 -1
- package/src/saas/internal-api/dbEmails/utils/util.js +10 -1
- package/src/saas/internal-api/projects/utils/utils.js +1 -1
- package/src/saas/internal-api/requests/api/requests.api.js +8 -2
- package/src/saas/internal-api/requests/api/requests.service.js +13 -1
- package/src/saas/internal-api/requests/models/create.request.model.js +5 -1
- package/src/saas/internal-api/requestsTable/api/requests.table.api.js +8 -2
- package/src/saas/internal-api/requestsTable/api/requests.table.service.js +6 -1
- package/src/saas/internal-api/requirements/api/requirements.service.js +16 -14
- package/src/saas/internal-api/requirements/models/update.requirement.model.js +1 -2
package/package.json
CHANGED
|
@@ -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
|
+
};
|
package/src/defaults/index.js
CHANGED
|
@@ -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 ${
|
|
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');
|
|
@@ -48,6 +50,7 @@ const getInternalAPI = () => {
|
|
|
48
50
|
requests,
|
|
49
51
|
coi,
|
|
50
52
|
compliance,
|
|
53
|
+
auditNotes,
|
|
51
54
|
reports,
|
|
52
55
|
users,
|
|
53
56
|
charts,
|
|
@@ -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,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
|
+
};
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
const auditApi = require('./audit.api');
|
|
2
2
|
const { AuditRequestModel, AuditListParametersModel, AuditDatesModel } = require('../../models/audit/audit.model');
|
|
3
3
|
const { validateType } = require('../../../../../common/validations/typeValidations');
|
|
4
|
-
const
|
|
4
|
+
const auditUtil = require('../../utils/auditUtil');
|
|
5
5
|
const dataTypeUtils = require('../../../../../common/utils/dataTypeUtils');
|
|
6
6
|
const { cloneObject } = require('../../../../../common/utils/objectUtils');
|
|
7
|
+
const complianceUtil = require('../../../../../common/utils/complianceUtil');
|
|
7
8
|
|
|
8
9
|
const audit = (auditRequestModel, context) => {
|
|
9
10
|
validateType(auditRequestModel, AuditRequestModel);
|
|
@@ -11,7 +12,7 @@ const audit = (auditRequestModel, context) => {
|
|
|
11
12
|
};
|
|
12
13
|
|
|
13
14
|
const isReaudit = (contractorId, context) => {
|
|
14
|
-
return
|
|
15
|
+
return complianceUtil.isReaudit(contractorId, context);
|
|
15
16
|
};
|
|
16
17
|
|
|
17
18
|
const getAuditorContractorList = (auditListParametersModel, context) => {
|
|
@@ -34,36 +35,21 @@ const getAuditMetadata = async (
|
|
|
34
35
|
requirementId,
|
|
35
36
|
recordId,
|
|
36
37
|
{
|
|
37
|
-
isProjectOnboarding
|
|
38
|
-
shouldSendNotificationToPM
|
|
39
|
-
} = {}
|
|
40
|
-
|
|
38
|
+
isProjectOnboarding,
|
|
39
|
+
shouldSendNotificationToPM
|
|
40
|
+
} = {}
|
|
41
|
+
) => {
|
|
42
|
+
return complianceUtil.getAuditMetadata(
|
|
43
|
+
auditorContext,
|
|
41
44
|
accountId,
|
|
42
45
|
projectId,
|
|
43
46
|
requirementId,
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
metadata.isReaudit = isReauditResponse.data.isReaudit;
|
|
51
|
-
|
|
52
|
-
const recordDetailsResponse = await getContractorDetailsForAudit(recordId, auditorContext);
|
|
53
|
-
const { vendorDetails } = recordDetailsResponse.data;
|
|
54
|
-
|
|
55
|
-
metadata.certificateId = vendorDetails.certificateDetails.certificateuploadId;
|
|
56
|
-
metadata.auditDates = {
|
|
57
|
-
contractorId: recordId,
|
|
58
|
-
contractorDateModified: vendorDetails.dateModified,
|
|
59
|
-
dateStartedAudit: recordDetailsResponse.dateStartedAudit,
|
|
60
|
-
contractorOverrideDateModified: vendorDetails.contractorOverrideDateModified,
|
|
61
|
-
contractCreateDate: vendorDetails.contractCreateDate
|
|
62
|
-
};
|
|
63
|
-
|
|
64
|
-
metadata.auditorId = await util.getAuditorId();
|
|
65
|
-
|
|
66
|
-
return metadata;
|
|
47
|
+
recordId,
|
|
48
|
+
{
|
|
49
|
+
isProjectOnboarding,
|
|
50
|
+
shouldSendNotificationToPM
|
|
51
|
+
}
|
|
52
|
+
);
|
|
67
53
|
};
|
|
68
54
|
|
|
69
55
|
const getAuditEntities = async (recordId, auditData, auditorContext) => {
|
|
@@ -72,7 +58,7 @@ const getAuditEntities = async (recordId, auditData, auditorContext) => {
|
|
|
72
58
|
|
|
73
59
|
const auditEntities = [];
|
|
74
60
|
auditData.forEach(auditEntity => auditEntities.push(
|
|
75
|
-
|
|
61
|
+
auditUtil.createAuditEntity(requirement, { ... auditEntity }))
|
|
76
62
|
);
|
|
77
63
|
return auditEntities;
|
|
78
64
|
};
|
|
@@ -129,7 +115,7 @@ const auditRecord = async function(
|
|
|
129
115
|
const auditMetadata = await getAuditMetadata(auditorContext, accountId, projectId, requirementId, recordId);
|
|
130
116
|
|
|
131
117
|
const auditApiConfig = dataTypeUtils.isObject(auditConfig) ?
|
|
132
|
-
|
|
118
|
+
auditUtil.parseAuditConfig(cloneObject(auditConfig)) :
|
|
133
119
|
auditConfig;
|
|
134
120
|
|
|
135
121
|
const auditEntities = await getAuditEntities(recordId, auditApiConfig, auditorContext);
|
|
@@ -145,8 +131,8 @@ module.exports = {
|
|
|
145
131
|
getAuditorContractorList,
|
|
146
132
|
getContractorDetailsForAudit,
|
|
147
133
|
getRequirementDetailsForAudit,
|
|
148
|
-
getAuditMetadata,
|
|
149
134
|
getAuditEntities,
|
|
135
|
+
getAuditMetadata,
|
|
150
136
|
getAuditRequestModel,
|
|
151
137
|
auditRecord
|
|
152
138
|
};
|
|
@@ -1,4 +1,9 @@
|
|
|
1
|
+
const { getEnv, getSystemUserIdentity } = require('../../../../../env');
|
|
2
|
+
const { credentials } = getEnv();
|
|
3
|
+
|
|
1
4
|
const coverageApi = require('./coverage.api');
|
|
5
|
+
const { getAuditMetadata } = require('../../../../../common/utils/complianceUtil');
|
|
6
|
+
const { getCoverageConfig } = require('../../utils/coverageUtil');
|
|
2
7
|
|
|
3
8
|
const saveCoverageNode = (coverage, nodeBackendSecret) => {
|
|
4
9
|
return coverageApi.saveCoverageNode(coverage, nodeBackendSecret);
|
|
@@ -16,9 +21,28 @@ const deleteCoverageByCoiId = (coiId, icsContext) => {
|
|
|
16
21
|
return coverageApi.deleteCoverageByCoiId(coiId, icsContext);
|
|
17
22
|
};
|
|
18
23
|
|
|
24
|
+
const addCoverage = async function(
|
|
25
|
+
accountId,
|
|
26
|
+
projectId,
|
|
27
|
+
requirementId,
|
|
28
|
+
recordId,
|
|
29
|
+
coverageConfig
|
|
30
|
+
) {
|
|
31
|
+
const { cookie: auditorContext } = getSystemUserIdentity(credentials.auditorUser);
|
|
32
|
+
const { auditDates } = await getAuditMetadata(accountId, projectId, requirementId, recordId, auditorContext);
|
|
33
|
+
|
|
34
|
+
const coverageApiConfig = dataTypeUtils.isObject(coverageConfig) ?
|
|
35
|
+
getCoverageConfig(cloneObject(coverageConfig)) :
|
|
36
|
+
coverageConfig;
|
|
37
|
+
|
|
38
|
+
const coverageResponse = await saveCoverageJava(auditorContext, auditDates, coverageApiConfig);
|
|
39
|
+
return coverageResponse;
|
|
40
|
+
};
|
|
41
|
+
|
|
19
42
|
module.exports = {
|
|
20
43
|
saveCoverageNode,
|
|
21
44
|
saveCoverageJava,
|
|
22
45
|
getCoverageByCoiId,
|
|
23
|
-
deleteCoverageByCoiId
|
|
46
|
+
deleteCoverageByCoiId,
|
|
47
|
+
addCoverage
|
|
24
48
|
};
|
|
@@ -3,7 +3,7 @@ const env = require('../../../../../env');
|
|
|
3
3
|
const waiveApi = require('./waive.api');
|
|
4
4
|
const { WaiveRequestModel, RetractRequestModel, WAIVER_REASONS } = require('../../models/waive/waive.model');
|
|
5
5
|
const { validateType } = require('../../../../../common/validations/typeValidations');
|
|
6
|
-
const
|
|
6
|
+
const auditUtil = require('../../utils/auditUtil');
|
|
7
7
|
const httpResponseStatusCodes = require('../../../../../common/httpResponseStatusCodes.json');
|
|
8
8
|
|
|
9
9
|
const { credentials } = env.getEnv();
|
|
@@ -29,7 +29,7 @@ const getWaiveModel = (
|
|
|
29
29
|
userId,
|
|
30
30
|
userRole
|
|
31
31
|
} = {}) => {
|
|
32
|
-
const auditId = getPolicyAuditIdFromRecord(record, policyName,
|
|
32
|
+
const auditId = getPolicyAuditIdFromRecord(record, policyName, auditUtil.getAttributeKey(attributeName));
|
|
33
33
|
userId = userId || env.getSystemUserIdentity(credentials.superUser).id;
|
|
34
34
|
userRole = userRole || userTypes.ICS;
|
|
35
35
|
|
|
@@ -55,13 +55,13 @@ const getWaiveModelByGap = (
|
|
|
55
55
|
userId,
|
|
56
56
|
userRole
|
|
57
57
|
} = {}) => {
|
|
58
|
-
const attributeName =
|
|
58
|
+
const attributeName = auditUtil.getAttributeNameByGap(record, policyName, gap);
|
|
59
59
|
|
|
60
60
|
return getWaiveModel(record, policyName, attributeName, reason, note, { userId, userRole });
|
|
61
61
|
};
|
|
62
62
|
|
|
63
63
|
const getRetractModel = (record, policyName, attributeName) => {
|
|
64
|
-
const auditId = getPolicyAuditIdFromRecord(record, policyName,
|
|
64
|
+
const auditId = getPolicyAuditIdFromRecord(record, policyName, auditUtil.getAttributeKey(attributeName));
|
|
65
65
|
const userId = env.getSystemUserIdentity(credentials.superUser).id;
|
|
66
66
|
const userRole = userTypes.ICS;
|
|
67
67
|
|
|
@@ -93,7 +93,7 @@ const getPolicyAuditIdFromRecord = (record, policyName, attributeName) => {
|
|
|
93
93
|
};
|
|
94
94
|
|
|
95
95
|
const waiveAll = async (record, context, { reason = WAIVER_REASONS.BUSINESS_DECISION, note = 'WAIVED AUTOMATICALLY' } = {}) => {
|
|
96
|
-
const allWaivablePolicies =
|
|
96
|
+
const allWaivablePolicies = auditUtil.getAllWaivablePolicies(record, context);
|
|
97
97
|
|
|
98
98
|
for (const waivable of allWaivablePolicies) {
|
|
99
99
|
const waiveModel = getWaiveModel(record, waivable.policyName, waivable.attributeName, reason, note);
|
|
@@ -4,9 +4,6 @@ const timeUtils = require('../../../../common/utils/timeUtils');
|
|
|
4
4
|
const auditModels = require('../models/audit/audit.model');
|
|
5
5
|
const waiveModels = require('../models/waive/waive.model');
|
|
6
6
|
|
|
7
|
-
const { getEnv, getSystemUserIdentity } = require('../../../../env');
|
|
8
|
-
const { credentials } = getEnv();
|
|
9
|
-
|
|
10
7
|
const emptyValue = '';
|
|
11
8
|
|
|
12
9
|
const getValueBySelection = selection => {
|
|
@@ -173,16 +170,10 @@ const createAuditEntity = (
|
|
|
173
170
|
return auditEntityModel;
|
|
174
171
|
};
|
|
175
172
|
|
|
176
|
-
const getAuditorId = () => {
|
|
177
|
-
const auditorIdentity = getSystemUserIdentity(credentials.auditorUser);
|
|
178
|
-
return auditorIdentity.id;
|
|
179
|
-
};
|
|
180
|
-
|
|
181
173
|
module.exports = {
|
|
182
174
|
parseAuditConfig,
|
|
183
175
|
getPolicyId,
|
|
184
176
|
createAuditEntity,
|
|
185
|
-
getAuditorId,
|
|
186
177
|
getAttributeKey,
|
|
187
178
|
getAttributeNameByGap,
|
|
188
179
|
getWaiveReason,
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
const { cloneObject } = require('../../../../common/utils/objectUtils');
|
|
2
|
+
const { policiesConfig } = require('../../../../defaults/configs/coverage');
|
|
3
|
+
|
|
4
|
+
const getCoverageConfig = function(coiId, policiesArr) {
|
|
5
|
+
const config = cloneObject(configBase);
|
|
6
|
+
|
|
7
|
+
config.coiId = coiId;
|
|
8
|
+
const coveragePolicies = config.documents[0].pages[0].policies;
|
|
9
|
+
|
|
10
|
+
for (const policyName of policiesArr) {
|
|
11
|
+
const policy = policiesConfig[policyName];
|
|
12
|
+
|
|
13
|
+
if (! policy) {
|
|
14
|
+
throw Error(`There is no config for ${policyName}. Config available for policies: ${Object.keys(policiesConfig).join(', ')}`);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
coveragePolicies.push(cloneObject(policy));
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return config;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const configBase = {
|
|
24
|
+
'coiId': 'REPLACE_WITH_REAL_VALUE',
|
|
25
|
+
'documents': [
|
|
26
|
+
{
|
|
27
|
+
'documentType': 'accord25',
|
|
28
|
+
'pages': [
|
|
29
|
+
{
|
|
30
|
+
'pageNumber': 1,
|
|
31
|
+
'policies': []
|
|
32
|
+
}
|
|
33
|
+
]
|
|
34
|
+
}
|
|
35
|
+
]
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
module.exports = {
|
|
39
|
+
getCoverageConfig
|
|
40
|
+
};
|
|
@@ -21,7 +21,8 @@ const Endpoints = {
|
|
|
21
21
|
updateContractorInviteDate: contractorId => `${backendUrl}/_saas/automation/contractor/${contractorId}/invite-date`,
|
|
22
22
|
searchInAutocomplete: ({ tabId, searchWord }) =>
|
|
23
23
|
`${backendUrl}/saas/requests/search/audited?&tabId=${tabId}&searchWord=${searchWord}`,
|
|
24
|
-
automationUpdateContractorUploadDate: contractorId => `${backendUrl}/saas/automation/contractor/${contractorId}/upload-date
|
|
24
|
+
automationUpdateContractorUploadDate: contractorId => `${backendUrl}/saas/automation/contractor/${contractorId}/upload-date`,
|
|
25
|
+
assignRequirement: recordId => `${backendUrl}/saas/contractor/${recordId}/assign-requirement`
|
|
25
26
|
};
|
|
26
27
|
|
|
27
28
|
const createContractor = (createContractorModel, context) => {
|
|
@@ -70,6 +71,10 @@ const changeRequirement = (recordModifyDateVerificationModel, context) => {
|
|
|
70
71
|
return requests.putRequestHandler(Endpoints.changeRequirement, recordModifyDateVerificationModel, context);
|
|
71
72
|
};
|
|
72
73
|
|
|
74
|
+
const assignRequirement = (recordId, assignRequirementModel, context) => {
|
|
75
|
+
return requests.putRequestHandler(Endpoints.assignRequirement(recordId), assignRequirementModel, context);
|
|
76
|
+
};
|
|
77
|
+
|
|
73
78
|
const sendGaps = (recordModifyDateVerificationModel, context) => {
|
|
74
79
|
return requests.postRequestHandler(Endpoints.sendGaps, recordModifyDateVerificationModel, context);
|
|
75
80
|
};
|
|
@@ -120,6 +125,7 @@ const updateContractorUploadDate = (contractorId, uploadDate, context) => {
|
|
|
120
125
|
module.exports = {
|
|
121
126
|
createContractor,
|
|
122
127
|
changeRequirement,
|
|
128
|
+
assignRequirement,
|
|
123
129
|
getContractorsByAccountId,
|
|
124
130
|
getContractorById,
|
|
125
131
|
getRecordHistory,
|
|
@@ -3,6 +3,7 @@ const { CreateContractorModel } = require('../models/create.contractor.model');
|
|
|
3
3
|
const { RequestModel } = require('../../requests/models/edit.request.model');
|
|
4
4
|
const { validateType } = require('../../../../common/validations/typeValidations');
|
|
5
5
|
const { RecordModifyDateVerificationModel } = require('../models/verification.contractor.model');
|
|
6
|
+
const { AssignRequirementModel } = require('../models/assign.requirement.model');
|
|
6
7
|
const httpResponseStatusCodes = require('../../../../common/httpResponseStatusCodes.json');
|
|
7
8
|
|
|
8
9
|
const createContractor = async (createContractorModel, context) => {
|
|
@@ -44,6 +45,10 @@ const updateExpiryDate = (contractorId, expiryDate, policyName) => {
|
|
|
44
45
|
return contractorsAPI.updateExpiryDate(contractorId, expiryDate, policyName);
|
|
45
46
|
};
|
|
46
47
|
|
|
48
|
+
const assignRequirement = (recordId, assignRequirementModel, context) => {
|
|
49
|
+
return contractorsAPI.assignRequirement(recordId, assignRequirementModel, context);
|
|
50
|
+
};
|
|
51
|
+
|
|
47
52
|
const updateInviteDate = (contractorId, inviteDate, context) => {
|
|
48
53
|
return contractorsAPI.updateInviteDate(contractorId, inviteDate, context);
|
|
49
54
|
};
|
|
@@ -127,6 +132,10 @@ const getRecordVerificationModel = async (recordId, context) => {
|
|
|
127
132
|
return new RecordModifyDateVerificationModel(recordData.id, { contractorDateModified: recordData.dateModified });
|
|
128
133
|
};
|
|
129
134
|
|
|
135
|
+
const getAssignRequirementModel = (requirementId, companyName, emailAddress) => {
|
|
136
|
+
return new AssignRequirementModel(requirementId, companyName, emailAddress);
|
|
137
|
+
};
|
|
138
|
+
|
|
130
139
|
module.exports = {
|
|
131
140
|
createContractor,
|
|
132
141
|
changeRequirement,
|
|
@@ -149,5 +158,7 @@ module.exports = {
|
|
|
149
158
|
unmuteNotifications,
|
|
150
159
|
deleteByContractorId,
|
|
151
160
|
deleteAllRecordsInAccount,
|
|
152
|
-
getRecordVerificationModel
|
|
161
|
+
getRecordVerificationModel,
|
|
162
|
+
assignRequirement,
|
|
163
|
+
getAssignRequirementModel
|
|
153
164
|
};
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
const createModel = require('./models/create.contractor.model');
|
|
2
2
|
const editModel = require('./models/edit.contractor.model');
|
|
3
3
|
const verificationModel = require('./models/verification.contractor.model');
|
|
4
|
+
const assignRequirementModel = require('./models/assign.requirement.model');
|
|
4
5
|
const services = require('./api/contractors.service');
|
|
5
6
|
|
|
6
|
-
const models = { create: createModel, edit: editModel, verification: verificationModel };
|
|
7
|
+
const models = { create: createModel, edit: editModel, verification: verificationModel, assignRequirementModel };
|
|
7
8
|
|
|
8
9
|
module.exports = { services, models };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
class AssignRequirementModel {
|
|
2
|
+
constructor(requirementId, companyName, emailAddress, { fileName = null, disableMail = false } = {}) {
|
|
3
|
+
this.requirementId = requirementId;
|
|
4
|
+
this.companyName = companyName;
|
|
5
|
+
this.emailAddress = emailAddress;
|
|
6
|
+
this.fileName = fileName;
|
|
7
|
+
this.disableMail = disableMail;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
module.exports = { AssignRequirementModel };
|
|
@@ -1,3 +1,35 @@
|
|
|
1
1
|
const DEFAULT_EMAIL_SENDER = 'hellogetjonestest@gmail.com';
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
const EMAIL_TYPES = {
|
|
4
|
+
COMPLIANT: 'compliant',
|
|
5
|
+
SEND_GAPS: 'sendGaps',
|
|
6
|
+
REQUEST_NEW_COI_EXPIRED: 'requestNewCoiExpired',
|
|
7
|
+
FIRST_REMINDER: 'firstReminder',
|
|
8
|
+
SECOND_REMINDER: 'secondReminder',
|
|
9
|
+
FINAL_REMINDER: 'finalReminder',
|
|
10
|
+
ABOUT_TO_EXPIRE_MONTH: 'aboutToExpireMonth',
|
|
11
|
+
ABOUT_TO_EXPIRE_TWO_WEEKS: 'aboutToExpireTwoWeeks',
|
|
12
|
+
ABOUT_TO_EXPIRE_WEEK: 'aboutToExpireWeek',
|
|
13
|
+
SAME_DAY_EXPIRATION_RECORD: 'sameDayExpirationRecord',
|
|
14
|
+
SAME_DAY_EXPIRATION_PM: 'sameDayExpirationPM',
|
|
15
|
+
REQUIREMENTS_UPDATED_NOTIFICATION: 'requirementsUpdatedNotification',
|
|
16
|
+
UPDATE_REQUIREMENTS_PREFIX: 'updatedRequirementsSubjectPrefix'
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const EMAIL_SUBJECT = {
|
|
20
|
+
compliant: ({ recordCompanyName }) => `Compliant COI - ${recordCompanyName}`,
|
|
21
|
+
sendGaps: ({ requesterName }) => `New Insurance Docs Required for ${requesterName}`, //doesn't includes text for guest or tenant
|
|
22
|
+
requestNewCoiExpired: ({ recordCompanyName }) => `${recordCompanyName}'s COI is`,
|
|
23
|
+
firstReminder: ({ requesterName }) => `We are still awaiting the Insurance Docs for ${requesterName}`,
|
|
24
|
+
secondReminder: ({ requesterName }) => `We are still awaiting the Insurance Docs for ${requesterName}`,
|
|
25
|
+
finalReminder: ({ recordCompanyName, requesterName }) => `Missing ${recordCompanyName}'s Insurance Docs for ${requesterName}`,
|
|
26
|
+
aboutToExpireMonth: ({ requesterName }) => `Your COI for ${requesterName} expires in 30 days`,
|
|
27
|
+
aboutToExpireTwoWeeks: ({ requesterName }) => `Your COI for ${requesterName} expires in 14 days`,
|
|
28
|
+
aboutToExpireWeek: ({ requesterName }) => `Only 7 days! Your COI for ${requesterName} expires`,
|
|
29
|
+
sameDayExpirationRecord: ({ requesterName }) => `Your COI for ${requesterName} expires TODAY`,
|
|
30
|
+
sameDayExpirationPM: ({ recordCompanyName }) => `COI expired for ${recordCompanyName} at`,
|
|
31
|
+
requirementsUpdatedNotification: ({ requesterName }) => `Updated Requirements - Your Insurance Docs are needed for ${requesterName}`,
|
|
32
|
+
updatedRequirementsSubjectPrefix: () => 'Updated Requirements - '
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
module.exports = { DEFAULT_EMAIL_SENDER, EMAIL_TYPES, EMAIL_SUBJECT };
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
const { EMAIL_SUBJECT } = require('../consts/consts');
|
|
2
|
+
|
|
1
3
|
const compareUnorderedArrays = (arr, other, { caseSensitive = true } = {}) => {
|
|
2
4
|
const isEachElementEqual = arr.sort().every((mail, i) => {
|
|
3
5
|
if (caseSensitive) {
|
|
@@ -51,9 +53,16 @@ const logRetrievedEmailInfo = (to, subject, { cc } = {}) => {
|
|
|
51
53
|
log += `\n| Subject: ${subject}`;
|
|
52
54
|
};
|
|
53
55
|
|
|
56
|
+
const getEmailTextInSubject = (recordCompanyName, emailType, isAfterUpdateRequirements = false, { requesterName = 'Default' } = {}) => {
|
|
57
|
+
const subject = EMAIL_SUBJECT[emailType]({ recordCompanyName, requesterName });
|
|
58
|
+
|
|
59
|
+
return isAfterUpdateRequirements ? `Updated Requirements - ${subject}` : subject;
|
|
60
|
+
};
|
|
61
|
+
|
|
54
62
|
module.exports = {
|
|
55
63
|
recipientsMatchVerification,
|
|
56
64
|
regexVerification,
|
|
57
65
|
extractEmailFromNameAndEmailFormat,
|
|
58
|
-
logRetrievedEmailInfo
|
|
66
|
+
logRetrievedEmailInfo,
|
|
67
|
+
getEmailTextInSubject
|
|
59
68
|
};
|
|
@@ -29,7 +29,7 @@ const getCreateProjectModel = (accountId, projectData) => {
|
|
|
29
29
|
projectData.city || projectData['City'] || 'N/A',
|
|
30
30
|
projectData.state || projectData['State'] || 'Alabama',
|
|
31
31
|
projectData.zipCode || projectData['Zip Code'] || '11111',
|
|
32
|
-
projectData.companyNameForProject || projectData['Company Name (for external communications)']
|
|
32
|
+
projectData.companyNameForProject || projectData['Company Name (for external communications)'] || projectData.name
|
|
33
33
|
);
|
|
34
34
|
return createProjectModel;
|
|
35
35
|
};
|
|
@@ -11,7 +11,8 @@ const Endpoints = {
|
|
|
11
11
|
getByTabId: `${backendUrl}/saas/requests`,
|
|
12
12
|
requestsGlobalSearch: (projectId, searchWord) =>
|
|
13
13
|
`${backendUrl}/saas/requests/search?&projectId=${projectId}&searchWord=${searchWord}`,
|
|
14
|
-
getAutocompleteAutoSelect: `${backendUrl}/saas/request/auto/selection
|
|
14
|
+
getAutocompleteAutoSelect: `${backendUrl}/saas/request/auto/selection`,
|
|
15
|
+
getTabTenantRequestsInProject: projectId => `${backendUrl}/saas/project/${projectId}/tenants/companies`
|
|
15
16
|
};
|
|
16
17
|
|
|
17
18
|
const createRequest = (createRequestModel, context) => {
|
|
@@ -53,6 +54,10 @@ const requestsGlobalSearch = (projectId, searchWord, context) => {
|
|
|
53
54
|
return requests.getRequestHandler(Endpoints.requestsGlobalSearch(projectId, searchWord), {}, context);
|
|
54
55
|
};
|
|
55
56
|
|
|
57
|
+
const getTabTenantRequestsInProject = (projectId, context) => {
|
|
58
|
+
return requests.getRequestHandler(Endpoints.getTabTenantRequestsInProject(projectId), {}, context);
|
|
59
|
+
};
|
|
60
|
+
|
|
56
61
|
module.exports = {
|
|
57
62
|
createRequest,
|
|
58
63
|
addRequestToRecord,
|
|
@@ -62,5 +67,6 @@ module.exports = {
|
|
|
62
67
|
getRequestsByAccountId,
|
|
63
68
|
getRequestsByTabId,
|
|
64
69
|
requestsGlobalSearch,
|
|
65
|
-
getAutocompleteAutoSelect
|
|
70
|
+
getAutocompleteAutoSelect,
|
|
71
|
+
getTabTenantRequestsInProject
|
|
66
72
|
};
|
|
@@ -79,6 +79,7 @@ const getOrCreateRequest = async (context, tabId, requirementId, contractor, act
|
|
|
79
79
|
}
|
|
80
80
|
|
|
81
81
|
const createContractorModel = getCreateRequestModel(requirementId, contractor, { tabId, sendMail });
|
|
82
|
+
//JON-8788: add optional parameter dateModified otherwise doesn't work for updated req
|
|
82
83
|
const createContractorResponse = await createRequest(createContractorModel, context);
|
|
83
84
|
return createContractorResponse.data;
|
|
84
85
|
};
|
|
@@ -87,6 +88,16 @@ const requestsGlobalSearch = (projectId, searchWord, context) => {
|
|
|
87
88
|
return requestsAPI.requestsGlobalSearch(projectId, searchWord, context);
|
|
88
89
|
};
|
|
89
90
|
|
|
91
|
+
const getTabTenantRequestsInProject = async (projectId, context) => {
|
|
92
|
+
const response = await requestsAPI.getTabTenantRequestsInProject(projectId, context);
|
|
93
|
+
|
|
94
|
+
if (response.status !== httpResponseStatusCodes.OK) {
|
|
95
|
+
throw Error(`Failed to get the tab tenants in project, status - ${response.status}`);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return response.data;
|
|
99
|
+
};
|
|
100
|
+
|
|
90
101
|
module.exports = {
|
|
91
102
|
createRequest,
|
|
92
103
|
getAutocompleteAutoSelect,
|
|
@@ -98,5 +109,6 @@ module.exports = {
|
|
|
98
109
|
getRequestsByAccountId,
|
|
99
110
|
getOrCreateRequest,
|
|
100
111
|
getCreateRequestModel,
|
|
101
|
-
requestsGlobalSearch
|
|
112
|
+
requestsGlobalSearch,
|
|
113
|
+
getTabTenantRequestsInProject
|
|
102
114
|
};
|
|
@@ -1,8 +1,12 @@
|
|
|
1
|
+
const env = require('../../../../../../../src/env');
|
|
2
|
+
|
|
1
3
|
const { validateType } = require('../../../../common/validations/typeValidations');
|
|
2
4
|
|
|
5
|
+
const superUserEmail = env.credentials.superUser;
|
|
6
|
+
|
|
3
7
|
function CreateRequestModel(requirementId, inviterEmail, vendorInfo, { tabId = null, sendMail = false, publicLink } = {}) {
|
|
4
8
|
this.reqId = requirementId;
|
|
5
|
-
this.inviterEmail = inviterEmail;
|
|
9
|
+
this.inviterEmail = inviterEmail || superUserEmail;
|
|
6
10
|
this.vendorInfo = vendorInfo;
|
|
7
11
|
this.disableMail = !sendMail;
|
|
8
12
|
this.tabId = tabId;
|
|
@@ -2,13 +2,19 @@ const { backendUrl } = require('../../../../env').getEnv();
|
|
|
2
2
|
const requests = require('../../../../common/requests/cookieAuth/requests');
|
|
3
3
|
|
|
4
4
|
const Endpoints = {
|
|
5
|
-
getRequestsByEmail: email => `${backendUrl}/saas/records/email/${email}
|
|
5
|
+
getRequestsByEmail: email => `${backendUrl}/saas/records/email/${email}`,
|
|
6
|
+
getGapsPageDataByRecordId: recordId => `${backendUrl}/saas/gaps/recordId/${recordId}`
|
|
6
7
|
};
|
|
7
8
|
|
|
8
9
|
const getRequestsByEmail = (email, context) => {
|
|
9
10
|
return requests.getRequestHandler(Endpoints.getRequestsByEmail(email), {}, context);
|
|
10
11
|
};
|
|
11
12
|
|
|
13
|
+
const getGapsPageDataByRecordId = (recordId, context) => {
|
|
14
|
+
return requests.getRequestHandler(Endpoints.getGapsPageDataByRecordId(recordId), {}, context);
|
|
15
|
+
};
|
|
16
|
+
|
|
12
17
|
module.exports = {
|
|
13
|
-
getRequestsByEmail
|
|
18
|
+
getRequestsByEmail,
|
|
19
|
+
getGapsPageDataByRecordId
|
|
14
20
|
};
|
|
@@ -4,6 +4,11 @@ const getRequestsByEmail = (email, context) => {
|
|
|
4
4
|
return requestsTableAPI.getRequestsByEmail(email, context);
|
|
5
5
|
};
|
|
6
6
|
|
|
7
|
+
const getGapsPageDataByRecordId = (recordId, context) => {
|
|
8
|
+
return requestsTableAPI.getGapsPageDataByRecordId(recordId, context);
|
|
9
|
+
};
|
|
10
|
+
|
|
7
11
|
module.exports = {
|
|
8
|
-
getRequestsByEmail
|
|
12
|
+
getRequestsByEmail,
|
|
13
|
+
getGapsPageDataByRecordId
|
|
9
14
|
};
|
|
@@ -68,22 +68,11 @@ const deleteRequirementByName = async (requirementName, tabId, context) => {
|
|
|
68
68
|
return deleteByRequirementId(requirementToDelete.id, context);
|
|
69
69
|
};
|
|
70
70
|
|
|
71
|
-
const getCreateRequirementModel = requirement => {
|
|
72
|
-
return requirementUtils.getCreateRequirementModel(requirement);
|
|
73
|
-
};
|
|
74
|
-
|
|
75
|
-
const getUpdatedRequirementModel = async (updatedRequirement, tabId, context) => {
|
|
76
|
-
const { name: requirementName } = updatedRequirement;
|
|
77
|
-
const existingRequirement = await getRequirementByName(tabId, requirementName, context);
|
|
78
|
-
updatedRequirement.dateModified = existingRequirement.dateModified;
|
|
79
|
-
|
|
80
|
-
return requirementUtils.getUpdateRequirementModel(updatedRequirement);
|
|
81
|
-
};
|
|
82
|
-
|
|
83
71
|
const deleteAllRequirementsInTabs = async (tabIds, context) => {
|
|
84
72
|
const failedToDeleteRequirements = [];
|
|
85
73
|
for (const tabId of tabIds) {
|
|
86
74
|
const { data: existingRequirements } = await getRequirementsByTabId(tabId, context);
|
|
75
|
+
|
|
87
76
|
for (const requirement of existingRequirements) {
|
|
88
77
|
const response = await deleteByRequirementId(requirement.id, context);
|
|
89
78
|
|
|
@@ -99,6 +88,19 @@ const deleteAllRequirementsInTabs = async (tabIds, context) => {
|
|
|
99
88
|
}
|
|
100
89
|
};
|
|
101
90
|
|
|
91
|
+
const getCreateRequirementModel = requirement => {
|
|
92
|
+
return requirementUtils.getCreateRequirementModel(requirement);
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
const getUpdatedRequirementModel = async (updatedRequirement, tabId, context, { originalRequirementName } = {}) => {
|
|
96
|
+
const requirementName = originalRequirementName || updatedRequirement.name;
|
|
97
|
+
const existingRequirement = await getRequirementByName(tabId, requirementName, context);
|
|
98
|
+
updatedRequirement.id = existingRequirement.id;
|
|
99
|
+
updatedRequirement.dateModified = existingRequirement.dateModified;
|
|
100
|
+
|
|
101
|
+
return requirementUtils.getUpdateRequirementModel(updatedRequirement);
|
|
102
|
+
};
|
|
103
|
+
|
|
102
104
|
module.exports = {
|
|
103
105
|
createRequirement,
|
|
104
106
|
getRequirementById,
|
|
@@ -110,7 +112,7 @@ module.exports = {
|
|
|
110
112
|
updateRequirementWithNotification,
|
|
111
113
|
deleteByRequirementId,
|
|
112
114
|
deleteRequirementByName,
|
|
115
|
+
deleteAllRequirementsInTabs,
|
|
113
116
|
getCreateRequirementModel,
|
|
114
|
-
getUpdatedRequirementModel
|
|
115
|
-
deleteAllRequirementsInTabs
|
|
117
|
+
getUpdatedRequirementModel
|
|
116
118
|
};
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
const { VENDORS } = require('../../../../common/consts/recordTypes');
|
|
2
1
|
const { validateType } = require('../../../../common/validations/typeValidations');
|
|
3
2
|
const { REQUIREMENT_SHARING_LEVELS } = require('../consts/consts');
|
|
4
3
|
const { PolicyModel } = require('./policy.model');
|
|
5
|
-
|
|
4
|
+
const { VENDORS } = require('../../../../common/consts/recordTypes');
|
|
6
5
|
class UpdateRequirementModel {
|
|
7
6
|
constructor({ id, name, policies, dateModified, sharingLevel = REQUIREMENT_SHARING_LEVELS.TAB, recordType = VENDORS }) {
|
|
8
7
|
this.id = id;
|