@getjones/test-infra 4.4.0 → 4.4.2
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 +35 -3
- package/src/common/consts/s3FileTypes.js +2 -1
- package/src/common/utils/complianceUtil.js +3 -1
- package/src/defaults/configs/auditConfigs.js +25 -0
- package/src/defaults/configs/polices.js +6 -1
- package/src/factory/records/records.js +18 -13
- package/src/resources/coi/coi2.pdf +0 -0
- package/src/resources/policy/policy.pdf +0 -0
- package/src/resources/virusFile.pdf +0 -0
- package/src/saas/internal-api/accountDirectory/api/accountDirectory.api.js +32 -2
- package/src/saas/internal-api/accountDirectory/api/accountDirectory.service.js +131 -5
- package/src/saas/internal-api/accountDirectory/models/accountDirectory.model.js +18 -3
- package/src/saas/internal-api/agreement/api/agreement.api.js +8 -2
- package/src/saas/internal-api/agreement/api/agreement.service.js +13 -1
- package/src/saas/internal-api/coi/api/coi.api.js +7 -2
- package/src/saas/internal-api/coi/api/coi.service.js +14 -1
- package/src/saas/internal-api/coi/models/Combine.last.two.cois.model.js +25 -0
- package/src/saas/internal-api/coi/utils/utils.js +48 -1
- package/src/saas/internal-api/compliance/api/audit/audit.api.js +14 -2
- package/src/saas/internal-api/compliance/api/audit/audit.service.js +47 -4
- package/src/saas/internal-api/compliance/api/overrideGap/override.gap.api.js +7 -2
- package/src/saas/internal-api/compliance/api/overrideGap/override.gap.service.js +62 -21
- package/src/saas/internal-api/compliance/consts/audit.js +8 -2
- package/src/saas/internal-api/compliance/models/audit/audit.model.js +2 -1
- package/src/saas/internal-api/compliance/utils/auditUtil.js +35 -3
- package/src/saas/internal-api/contractors/api/contractors.api.js +6 -0
- package/src/saas/internal-api/contractors/api/contractors.service.js +25 -1
- package/src/saas/internal-api/uploadFiles/api/upload.file.api.js +6 -0
- package/src/saas/internal-api/uploadFiles/api/upload.file.service.js +13 -0
- package/src/saas/openapi/coi/coi.service.js +0 -1
- package/src/saas/openapi/requirements/requirements.api.js +11 -2
- package/src/saas/openapi/requirements/requirements.service.js +13 -1
|
@@ -2,8 +2,10 @@ const fs = require('fs');
|
|
|
2
2
|
|
|
3
3
|
const services = require('../api/coi.service');
|
|
4
4
|
const { SubmitCoiModel } = require('../models/submit.coi.model');
|
|
5
|
+
const { CombineLastTwoCOIsModel } = require('../models/Combine.last.two.cois.model');
|
|
5
6
|
const { getContractorById } = require('../../contractors/api/contractors.service');
|
|
6
7
|
const { getIcsCookie } = require('../../auth/api/auth.service');
|
|
8
|
+
const timeUtils = require('../../../../common/utils/timeUtils');
|
|
7
9
|
|
|
8
10
|
const uploadFileToStorage = (recordId, filePath) => {
|
|
9
11
|
const fileData = fs.createReadStream(filePath);
|
|
@@ -63,8 +65,53 @@ const uploadCoi = async (
|
|
|
63
65
|
return uploadedCoi;
|
|
64
66
|
};
|
|
65
67
|
|
|
68
|
+
const waitForAntiVirusRecordCoiScanToFinish = async (recordId, context, { maxSecondToWait = 10 } = {}) => {
|
|
69
|
+
let isScanned = false;
|
|
70
|
+
const oneSecondInMilliseconds = 1000;
|
|
71
|
+
let timeFromTheStart = 0;
|
|
72
|
+
let coiLink;
|
|
73
|
+
const started = Date.now();
|
|
74
|
+
|
|
75
|
+
const { data: record } = await getContractorById(recordId, context);
|
|
76
|
+
|
|
77
|
+
while (!isScanned && timeFromTheStart < maxSecondToWait) {
|
|
78
|
+
({ data: coiLink } = await services.getCoiPreSignedUrl(record.certificatePdf));
|
|
79
|
+
isScanned = coiLink.isInProgress;
|
|
80
|
+
const now = Date.now();
|
|
81
|
+
timeFromTheStart = (now - started) / oneSecondInMilliseconds;
|
|
82
|
+
await timeUtils.waitFor(1).seconds;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return coiLink.coiPreSignedUrl;
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
const combineLastTwoCOIs = async ({
|
|
89
|
+
recordId,
|
|
90
|
+
fileIds,
|
|
91
|
+
uploadedBy,
|
|
92
|
+
uploaderEmail,
|
|
93
|
+
isContractorExist,
|
|
94
|
+
icsContext,
|
|
95
|
+
auditorContext
|
|
96
|
+
}) => {
|
|
97
|
+
const recordResponse = await getContractorById(recordId, icsContext);
|
|
98
|
+
const recordDateModified = recordResponse.data.dateModified;
|
|
99
|
+
|
|
100
|
+
const combineLastTwoCOIsModel = new CombineLastTwoCOIsModel({
|
|
101
|
+
recordId,
|
|
102
|
+
fileIds,
|
|
103
|
+
uploadedBy,
|
|
104
|
+
uploaderEmail,
|
|
105
|
+
recordDateModified,
|
|
106
|
+
isContractorExist
|
|
107
|
+
});
|
|
108
|
+
return services.combineLastTwoCOIs(combineLastTwoCOIsModel, auditorContext);
|
|
109
|
+
};
|
|
110
|
+
|
|
66
111
|
module.exports = {
|
|
67
112
|
uploadCoi,
|
|
68
113
|
uploadFileToStorage,
|
|
69
|
-
submitCoiFilesUpload
|
|
114
|
+
submitCoiFilesUpload,
|
|
115
|
+
waitForAntiVirusRecordCoiScanToFinish,
|
|
116
|
+
combineLastTwoCOIs
|
|
70
117
|
};
|
|
@@ -5,6 +5,7 @@ const Endpoints = {
|
|
|
5
5
|
auditorContractorList: `${backendUrl}/saas/auditor/contractors`,
|
|
6
6
|
audit: `${backendUrl}/saas/auditor/contractors/submit/audits`,
|
|
7
7
|
enterAudit: contractorId => `${backendUrl}/saas/auditor/contractors/${contractorId}/master-audit`,
|
|
8
|
+
verifyAudit: contractorId => `${backendUrl}/saas/auditor/audit/${contractorId}/verify`,
|
|
8
9
|
getAuditRecordModelByRecordId: recordId => `${backendUrl}/saas/auditor/record/${recordId}/audit-record`,
|
|
9
10
|
getComplianceJsonByRecordId: recordId => `${backendUrl}/saas/contractors/${recordId}/compliance-json`,
|
|
10
11
|
requirementDetailsForAudit: contractorId => `${backendUrl}/saas/auditor/contractor/${contractorId}/requirement`,
|
|
@@ -15,7 +16,8 @@ const Endpoints = {
|
|
|
15
16
|
putAuditOnHold: `${backendUrl}/saas/auditor/put-on-hold`,
|
|
16
17
|
resumeAudit: onHoldId => `${backendUrl}/saas/auditor/on-hold/${onHoldId}/resume`,
|
|
17
18
|
getAuditMetadata: auditId => `${backendUrl}/saas/auditor/audit-metadata/${auditId}`,
|
|
18
|
-
updateComplianceAuditActionsDate: recordId => `${backendUrl}/saas/automation/record/${recordId}/update-audit-actions-date
|
|
19
|
+
updateComplianceAuditActionsDate: recordId => `${backendUrl}/saas/automation/record/${recordId}/update-audit-actions-date`,
|
|
20
|
+
auditRawData: recordId => `${backendUrl}/saas/integration-tests/record/${recordId}/audit/raw`
|
|
19
21
|
};
|
|
20
22
|
|
|
21
23
|
const audit = async (contractorId, auditRequestModel, context) => {
|
|
@@ -46,6 +48,10 @@ const enterAudit = (contractorId, context) => {
|
|
|
46
48
|
return requests.getRequestHandler(Endpoints.enterAudit(contractorId), {}, context);
|
|
47
49
|
};
|
|
48
50
|
|
|
51
|
+
const verifyAuditBeforeEnter = (contractorId, context) => {
|
|
52
|
+
return requests.getRequestHandler(Endpoints.verifyAudit(contractorId), {}, context);
|
|
53
|
+
};
|
|
54
|
+
|
|
49
55
|
const getAuditRecordModel = (recordId, context) => {
|
|
50
56
|
return requests.getRequestHandler(Endpoints.getAuditRecordModelByRecordId(recordId), {}, context);
|
|
51
57
|
};
|
|
@@ -84,6 +90,10 @@ const getComplianceJson = (recordId, context) => {
|
|
|
84
90
|
return requests.getRequestHandler(Endpoints.getComplianceJsonByRecordId(recordId), {}, context);
|
|
85
91
|
};
|
|
86
92
|
|
|
93
|
+
const getAuditRawData = (recordId, context) => {
|
|
94
|
+
return requests.getRequestHandler(Endpoints.auditRawData(recordId), {}, context);
|
|
95
|
+
};
|
|
96
|
+
|
|
87
97
|
module.exports = {
|
|
88
98
|
audit,
|
|
89
99
|
submitAudit,
|
|
@@ -99,5 +109,7 @@ module.exports = {
|
|
|
99
109
|
putAuditOnHold,
|
|
100
110
|
resumeAudit,
|
|
101
111
|
getAuditMetadata,
|
|
102
|
-
updateComplianceAuditActionsDate
|
|
112
|
+
updateComplianceAuditActionsDate,
|
|
113
|
+
getAuditRawData,
|
|
114
|
+
verifyAuditBeforeEnter
|
|
103
115
|
};
|
|
@@ -35,8 +35,24 @@ const getAuditorContractorList = (auditListParametersModel, context) => {
|
|
|
35
35
|
return auditApi.getAuditorContractorList(auditListParametersModel, context);
|
|
36
36
|
};
|
|
37
37
|
|
|
38
|
-
const
|
|
39
|
-
|
|
38
|
+
const getAuditRequestModelAfterEnterAudit = async (auditConfigForModelAfterEnterAudit, accountId, projectId, requirementId, recordId, context) => {
|
|
39
|
+
const metadata = await prepareMetadataForAudit(context, accountId, projectId, requirementId, recordId);
|
|
40
|
+
const auditEntities = await getAuditEntities(recordId, auditConfigForModelAfterEnterAudit, context);
|
|
41
|
+
const auditRequestModel = getAuditRequestModel(metadata, auditEntities);
|
|
42
|
+
|
|
43
|
+
return auditRequestModel;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const enterAudit = async (recordId, context, { auditConfigForModelAfterEnterAudit, accountId, projectId, requirementId } = {}) => {
|
|
47
|
+
const enterAuditResponse = await auditApi.enterAudit(recordId, context);
|
|
48
|
+
|
|
49
|
+
if (enterAuditResponse.status !== httpResponseStatusCodes.OK) {
|
|
50
|
+
throw Error(`Failed to enter audit\n$response - ${enterAuditResponse.status}\n${JSON.stringify(enterAuditResponse.data)}`);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return auditConfigForModelAfterEnterAudit ?
|
|
54
|
+
getAuditRequestModelAfterEnterAudit(auditConfigForModelAfterEnterAudit, accountId, projectId, requirementId, recordId, context) :
|
|
55
|
+
enterAuditResponse;
|
|
40
56
|
};
|
|
41
57
|
|
|
42
58
|
const getAuditRecordModel = (recordId, context) => {
|
|
@@ -46,6 +62,15 @@ const getAuditRecordModel = (recordId, context) => {
|
|
|
46
62
|
const getRequirementDetailsForAudit = (contractorId, context) => {
|
|
47
63
|
return auditApi.getRequirementDetailsForAudit(contractorId, context);
|
|
48
64
|
};
|
|
65
|
+
const getAuditorContractorReviewByRecordId = async (recordId, context) => {
|
|
66
|
+
const response = await auditApi.getAuditorContractorReviewByRecordId(recordId, context);
|
|
67
|
+
|
|
68
|
+
if (response.status !== httpResponseStatusCodes.OK) {
|
|
69
|
+
throw Error(`Failed to get auditor review fields from recordId - ${recordId} error status ${response.status}`);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return response.data;
|
|
73
|
+
};
|
|
49
74
|
|
|
50
75
|
const prepareMetadataForAudit = async (
|
|
51
76
|
auditorContext,
|
|
@@ -83,11 +108,12 @@ const getAuditByRecordId = async (recordId, context, { isRecordDeleted } = {}) =
|
|
|
83
108
|
|
|
84
109
|
const getAuditEntities = async (recordId, auditData, auditorContext) => {
|
|
85
110
|
const requirementDetailsForAuditResponse = await getRequirementDetailsForAudit(recordId, auditorContext);
|
|
111
|
+
const previousAuditData = await getAuditRawData(recordId, auditorContext);
|
|
86
112
|
const requirement = requirementDetailsForAuditResponse.data;
|
|
87
113
|
|
|
88
114
|
const auditEntities = [];
|
|
89
115
|
auditData.forEach(auditEntity => auditEntities.push(
|
|
90
|
-
auditUtil.createAuditEntity(requirement, { ... auditEntity }))
|
|
116
|
+
auditUtil.createAuditEntity(requirement, previousAuditData, { ... auditEntity }))
|
|
91
117
|
);
|
|
92
118
|
return auditEntities;
|
|
93
119
|
};
|
|
@@ -231,6 +257,20 @@ const getCurrentAuditUniqueCoiId = async function(recordId, auditorContext) {
|
|
|
231
257
|
return uniqueCoiId;
|
|
232
258
|
};
|
|
233
259
|
|
|
260
|
+
const getAuditRawData = async function(recordId, context) {
|
|
261
|
+
const responseAudit = await auditApi.getAuditRawData(recordId, context);
|
|
262
|
+
|
|
263
|
+
if (responseAudit.status !== httpResponseStatusCodes.OK) {
|
|
264
|
+
throw Error(`Failed to get audit raw data by record id\n${responseAudit}`);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
return responseAudit.data;
|
|
268
|
+
};
|
|
269
|
+
|
|
270
|
+
const getAttributeKey = attributeName => {
|
|
271
|
+
return auditUtil.getAttributeKey(attributeName);
|
|
272
|
+
};
|
|
273
|
+
|
|
234
274
|
module.exports = {
|
|
235
275
|
audit,
|
|
236
276
|
submitAudit,
|
|
@@ -253,5 +293,8 @@ module.exports = {
|
|
|
253
293
|
getAuditOnHoldData,
|
|
254
294
|
getLastAuditDateBeforeAgreementAudit,
|
|
255
295
|
updateComplianceAuditActionsDate,
|
|
256
|
-
getCurrentAuditUniqueCoiId
|
|
296
|
+
getCurrentAuditUniqueCoiId,
|
|
297
|
+
getAuditRawData,
|
|
298
|
+
getAuditorContractorReviewByRecordId,
|
|
299
|
+
getAttributeKey
|
|
257
300
|
};
|
|
@@ -5,7 +5,8 @@ const Endpoints = {
|
|
|
5
5
|
waive: contractorId => `${backendUrl}/saas/contractors/${contractorId}/waiver`,
|
|
6
6
|
retract: contractorId => `${backendUrl}/saas/contractors/${contractorId}/waiver`,
|
|
7
7
|
overrideGap: `${backendUrl}/saas/record/override-gap`,
|
|
8
|
-
retractOverride: `${backendUrl}/saas/record/retract-override
|
|
8
|
+
retractOverride: `${backendUrl}/saas/record/retract-override`,
|
|
9
|
+
getOverridesByRecordId: recordId => `${backendUrl}/saas/integration-tests/record/${recordId}/override`
|
|
9
10
|
};
|
|
10
11
|
|
|
11
12
|
const waive = async (contractorId, waiveRequestModel, context) => {
|
|
@@ -30,4 +31,8 @@ const retractOverride = (retractRequestModel, context) => {
|
|
|
30
31
|
return requests.postRequestHandler(Endpoints.retractOverride, retractRequestModel, context);
|
|
31
32
|
};
|
|
32
33
|
|
|
33
|
-
|
|
34
|
+
const getOverridesByRecordId = (recordId, context) => {
|
|
35
|
+
return requests.getRequestHandler(Endpoints.getOverridesByRecordId(recordId), {}, context);
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
module.exports = { waive, retract, overrideGap, retractOverride, getOverridesByRecordId };
|
|
@@ -29,7 +29,7 @@ const retractOverride = (retractRequestModel, context) => {
|
|
|
29
29
|
return overrideGapApi.retractOverride(retractRequestModel, context);
|
|
30
30
|
};
|
|
31
31
|
|
|
32
|
-
const
|
|
32
|
+
const getAllWaiveModels = (
|
|
33
33
|
record,
|
|
34
34
|
policyName,
|
|
35
35
|
attributeName,
|
|
@@ -39,20 +39,40 @@ const getWaiveModel = (
|
|
|
39
39
|
userId,
|
|
40
40
|
userRole
|
|
41
41
|
} = {}) => {
|
|
42
|
-
const
|
|
42
|
+
const auditIds = getPolicyAuditIdsFromRecord(record, policyName, auditUtil.getAttributeKey(attributeName));
|
|
43
43
|
userId = userId || env.getSystemUserIdentity(credentials.superUser).id;
|
|
44
44
|
userRole = userRole || userTypes.ICS;
|
|
45
45
|
|
|
46
|
-
const
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
46
|
+
const waiverModels = [];
|
|
47
|
+
let i = 0;
|
|
48
|
+
while (i < auditIds.length) {
|
|
49
|
+
const auditId = auditIds[i];
|
|
50
|
+
const waiveModel = new WaiveRequestModel({
|
|
51
|
+
contractorId: record.id,
|
|
52
|
+
auditId,
|
|
53
|
+
waiverReason,
|
|
54
|
+
remarks,
|
|
55
|
+
userId,
|
|
56
|
+
userRole
|
|
57
|
+
});
|
|
58
|
+
waiverModels.push(waiveModel);
|
|
59
|
+
i++;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return waiverModels;
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
const getWaiveModel = (
|
|
66
|
+
record,
|
|
67
|
+
policyName,
|
|
68
|
+
attributeName,
|
|
69
|
+
waiverReason,
|
|
70
|
+
remarks,
|
|
71
|
+
{
|
|
51
72
|
userId,
|
|
52
73
|
userRole
|
|
53
|
-
})
|
|
54
|
-
|
|
55
|
-
return waiveModel;
|
|
74
|
+
} = {}) => {
|
|
75
|
+
return getAllWaiveModels(record, policyName, attributeName, waiverReason, remarks, { userId, userRole })[0];
|
|
56
76
|
};
|
|
57
77
|
|
|
58
78
|
const getWaiveModelByGap = (
|
|
@@ -71,7 +91,7 @@ const getWaiveModelByGap = (
|
|
|
71
91
|
};
|
|
72
92
|
|
|
73
93
|
const getRetractModel = (record, policyName, attributeName) => {
|
|
74
|
-
const auditId =
|
|
94
|
+
const auditId = getPolicyAuditIdsFromRecord(record, policyName, auditUtil.getAttributeKey(attributeName))[0];
|
|
75
95
|
const userId = env.getSystemUserIdentity(credentials.superUser).id;
|
|
76
96
|
const userRole = userTypes.ICS;
|
|
77
97
|
|
|
@@ -85,7 +105,7 @@ const getRetractModel = (record, policyName, attributeName) => {
|
|
|
85
105
|
return retractModel;
|
|
86
106
|
};
|
|
87
107
|
|
|
88
|
-
const
|
|
108
|
+
const getPolicyAuditIdsFromRecord = (record, policyName, attributeName) => {
|
|
89
109
|
const policy = record.reviewbyAuditor.find(contractorCoverage =>
|
|
90
110
|
contractorCoverage.insuranceName === policyName);
|
|
91
111
|
|
|
@@ -93,25 +113,35 @@ const getPolicyAuditIdFromRecord = (record, policyName, attributeName) => {
|
|
|
93
113
|
throw new Error(`Policy name: ${policyName} don't exist in record`);
|
|
94
114
|
}
|
|
95
115
|
|
|
96
|
-
const
|
|
116
|
+
const attributes = policy.errorList.filter(error => error.limitname === attributeName);
|
|
97
117
|
|
|
98
|
-
if (!
|
|
118
|
+
if (!attributes.length) {
|
|
99
119
|
throw new Error(`Attribute name: ${attributeName} don't exist in record`);
|
|
100
120
|
}
|
|
101
121
|
|
|
102
|
-
|
|
122
|
+
const auditIds = attributes.map(a => a.auditId);
|
|
123
|
+
|
|
124
|
+
return auditIds;
|
|
103
125
|
};
|
|
104
126
|
|
|
105
127
|
// private method - please refer to waiveAll / acceptAll
|
|
106
128
|
const overrideAll = async (record, reason, context, { note = 'OVERRIDDEN AUTOMATICALLY' } = {}) => {
|
|
107
|
-
|
|
129
|
+
let allWaivablePolicies = auditUtil.getAllWaivablePolicies(record, context);
|
|
130
|
+
// Remove duplicates, this can happen for example in case of multiple errors on Additional Insured, Certificate Holder or Additional Information
|
|
131
|
+
allWaivablePolicies = allWaivablePolicies.filter((value, index, self) =>
|
|
132
|
+
index === self.findIndex(t => (
|
|
133
|
+
t.policyName === value.policyName && t.attributeName === value.attributeName
|
|
134
|
+
))
|
|
135
|
+
);
|
|
108
136
|
|
|
109
137
|
for (const waivable of allWaivablePolicies) {
|
|
110
|
-
const
|
|
111
|
-
|
|
138
|
+
const waiveModels = getAllWaiveModels(record, waivable.policyName, waivable.attributeName, reason, note);
|
|
139
|
+
for (waiveModel of waiveModels) {
|
|
140
|
+
const waiveResponse = await overrideGap({ waiveRequestModel: waiveModel, context });
|
|
112
141
|
|
|
113
|
-
|
|
114
|
-
|
|
142
|
+
if (waiveResponse.status !== httpResponseStatusCodes.OK) {
|
|
143
|
+
throw Error(`Failed to waive ${waivable.policyName} - ${waivable.attributeName} for ${record.company}`);
|
|
144
|
+
}
|
|
115
145
|
}
|
|
116
146
|
}
|
|
117
147
|
};
|
|
@@ -128,6 +158,16 @@ const acceptAll = async (record, context, { note = 'ACCEPTED AUTOMATICALLY' } =
|
|
|
128
158
|
await overrideAll(record, WAIVER_REASONS.ACCEPT_NO_EXPOSURE, context, { note });
|
|
129
159
|
};
|
|
130
160
|
|
|
161
|
+
const getOverridesByRecordId = async function(recordId, context) {
|
|
162
|
+
const responseAudit = await overrideGapApi.getOverridesByRecordId(recordId, context);
|
|
163
|
+
|
|
164
|
+
if (responseAudit.status !== httpResponseStatusCodes.OK) {
|
|
165
|
+
throw Error(`Failed to get overrides by record id\n${responseAudit}`);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
return responseAudit.data;
|
|
169
|
+
};
|
|
170
|
+
|
|
131
171
|
module.exports = {
|
|
132
172
|
waive,
|
|
133
173
|
waiveAll,
|
|
@@ -137,5 +177,6 @@ module.exports = {
|
|
|
137
177
|
getRetractModel,
|
|
138
178
|
getWaiveModelByGap,
|
|
139
179
|
overrideGap,
|
|
140
|
-
retractOverride
|
|
180
|
+
retractOverride,
|
|
181
|
+
getOverridesByRecordId
|
|
141
182
|
};
|
|
@@ -47,7 +47,7 @@ const ATTRIBUTE_NAMES_MAP = {
|
|
|
47
47
|
isPolicyExist: 'coverageexists',
|
|
48
48
|
eachOccurrence: 'Each Occurrence',
|
|
49
49
|
expiryDate: 'expirydate',
|
|
50
|
-
policyNumber: '
|
|
50
|
+
policyNumber: 'policynumber',
|
|
51
51
|
perOccurrence: 'PerOccur',
|
|
52
52
|
perPolicy: 'Per Policy',
|
|
53
53
|
perProject: 'Per Project',
|
|
@@ -83,6 +83,11 @@ const auditStatus = {
|
|
|
83
83
|
canceled: 'CANCELED'
|
|
84
84
|
};
|
|
85
85
|
|
|
86
|
+
const auditTypes = {
|
|
87
|
+
manual: 'MANUAL',
|
|
88
|
+
automatic: 'AUTOMATIC'
|
|
89
|
+
};
|
|
90
|
+
|
|
86
91
|
const auditOnHoldReason = {
|
|
87
92
|
ESCALATION_TO_PM: 'Escalation to PM',
|
|
88
93
|
ISSUE_WITH_REQUIREMENTS: 'Issue with Requirements',
|
|
@@ -100,5 +105,6 @@ module.exports = {
|
|
|
100
105
|
VALID_SCORES,
|
|
101
106
|
auditTriggerType,
|
|
102
107
|
auditStatus,
|
|
103
|
-
auditOnHoldReason
|
|
108
|
+
auditOnHoldReason,
|
|
109
|
+
auditTypes
|
|
104
110
|
};
|
|
@@ -42,11 +42,12 @@ class AuditRequestModel {
|
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
class AuditEntityModel {
|
|
45
|
-
constructor(policyId, attributeName, status, value) {
|
|
45
|
+
constructor(policyId, attributeName, status, value, auditorReviewId) {
|
|
46
46
|
this.contractorInsuranceId = policyId;
|
|
47
47
|
this.limitname = attributeName;
|
|
48
48
|
this.status = status;
|
|
49
49
|
this.value = value;
|
|
50
|
+
this.auditorReviewId = auditorReviewId;
|
|
50
51
|
}
|
|
51
52
|
}
|
|
52
53
|
|
|
@@ -83,6 +83,13 @@ const getPolicyId = (policyName, requirement) => {
|
|
|
83
83
|
return policy.id;
|
|
84
84
|
};
|
|
85
85
|
|
|
86
|
+
const getAuditorReviewIdFromPreviousAudit = (policyId, attributeName, previousAuditData) => {
|
|
87
|
+
const reviewField = previousAuditData.
|
|
88
|
+
find(reviewField => reviewField.insuranceTypeId === policyId && reviewField.limitName === attributeName);
|
|
89
|
+
|
|
90
|
+
return reviewField?.auditorcontractorId;
|
|
91
|
+
};
|
|
92
|
+
|
|
86
93
|
const parseAuditConfig = function(config) {
|
|
87
94
|
const auditDataArr = [];
|
|
88
95
|
for (const field in config) {
|
|
@@ -142,7 +149,22 @@ const parseAuditConfig = function(config) {
|
|
|
142
149
|
|
|
143
150
|
if (isArray(config[field])) {
|
|
144
151
|
selection.status = AUDIT_ENTITY_STATUSES[(config[field][0]).toUpperCase()];
|
|
145
|
-
|
|
152
|
+
|
|
153
|
+
const auditValue = config[field][1];
|
|
154
|
+
|
|
155
|
+
if (multipleErrorsEndorsementAndAttributesList.includes(field) && isArray(auditValue)) {
|
|
156
|
+
// in case of 'Other' with multiple errors in special policies (Additional Information, Certificate Holder, etc)
|
|
157
|
+
let i = 0;
|
|
158
|
+
while (i < auditValue.length) {
|
|
159
|
+
const copiedSelection = { ... selection };
|
|
160
|
+
copiedSelection.value = auditValue[i];
|
|
161
|
+
auditDataArr.push(copiedSelection);
|
|
162
|
+
i++;
|
|
163
|
+
}
|
|
164
|
+
continue;
|
|
165
|
+
} else {
|
|
166
|
+
selection.value = auditValue; // Ok to be undefined
|
|
167
|
+
}
|
|
146
168
|
} else {
|
|
147
169
|
selection.status = AUDIT_ENTITY_STATUSES[(config[field]).toUpperCase()] || AUDIT_ENTITY_STATUSES.YES;
|
|
148
170
|
selection.value = getValueBySelection(config[field]);
|
|
@@ -159,14 +181,16 @@ const parseAuditConfig = function(config) {
|
|
|
159
181
|
};
|
|
160
182
|
|
|
161
183
|
const createAuditEntity = (
|
|
162
|
-
requirement, {
|
|
184
|
+
requirement, previousAuditData, {
|
|
163
185
|
policyName = null,
|
|
164
186
|
attributeName = null,
|
|
165
187
|
value = emptyValue,
|
|
166
188
|
status = emptyValue
|
|
167
189
|
}) => {
|
|
168
190
|
const policyId = getPolicyId(policyName, requirement);
|
|
169
|
-
const
|
|
191
|
+
const auditorReviewId = getAuditorReviewIdFromPreviousAudit(policyId, attributeName, previousAuditData);
|
|
192
|
+
const auditEntityModel = new auditModels.AuditEntityModel(policyId, attributeName, status, value, auditorReviewId);
|
|
193
|
+
|
|
170
194
|
return auditEntityModel;
|
|
171
195
|
};
|
|
172
196
|
|
|
@@ -188,6 +212,14 @@ const certificateEndorsementsList = [
|
|
|
188
212
|
'Agreement'
|
|
189
213
|
];
|
|
190
214
|
|
|
215
|
+
const multipleErrorsEndorsementAndAttributesList = [
|
|
216
|
+
'Certificate Holder',
|
|
217
|
+
'Additional Information',
|
|
218
|
+
'Additional Insured',
|
|
219
|
+
'Agreement',
|
|
220
|
+
'Other'
|
|
221
|
+
];
|
|
222
|
+
|
|
191
223
|
const specialAttributes = {
|
|
192
224
|
'Certificate issue date': 'certIssueDate',
|
|
193
225
|
'Cancellation Terms': 'cancellationTerms',
|
|
@@ -7,6 +7,7 @@ const Endpoints = {
|
|
|
7
7
|
get: `${backendUrl}/saas/contractors`,
|
|
8
8
|
getContractorById: contractorId => `${backendUrl}/saas/contractor/${contractorId}`,
|
|
9
9
|
getRecordHistory: contractorId => `${backendUrl}/saas/record/${contractorId}/history`,
|
|
10
|
+
getRecordHistoryEventReport: recordHistoryId => `${backendUrl}/saas/record/compliance-history-report/${recordHistoryId}`,
|
|
10
11
|
getRecordOcrStatus: contractorId => `${backendUrl}/saas/contractor/${contractorId}/ocr/status`,
|
|
11
12
|
delete: contractorId => `${backendUrl}/saas/contractor/${contractorId}`,
|
|
12
13
|
archive: contractorId => `${backendUrl}/saas/contractor/${contractorId}/archive`,
|
|
@@ -48,6 +49,10 @@ const getRecordHistory = (contractorId, context) => {
|
|
|
48
49
|
return requests.getRequestHandler(Endpoints.getRecordHistory(contractorId), {}, context);
|
|
49
50
|
};
|
|
50
51
|
|
|
52
|
+
const getRecordHistoryEventReport = (recordHistoryId, context) => {
|
|
53
|
+
return requests.getRequestHandler(Endpoints.getRecordHistoryEventReport(recordHistoryId), {}, context);
|
|
54
|
+
};
|
|
55
|
+
|
|
51
56
|
const getComplianceReport = (encryptedData, context) => {
|
|
52
57
|
return requests.getRequestHandler(Endpoints.getComplianceReport(encryptedData), {}, context);
|
|
53
58
|
};
|
|
@@ -170,6 +175,7 @@ module.exports = {
|
|
|
170
175
|
getContractorsByAccountId,
|
|
171
176
|
getContractorById,
|
|
172
177
|
getRecordHistory,
|
|
178
|
+
getRecordHistoryEventReport,
|
|
173
179
|
getRecordOcrStatus,
|
|
174
180
|
getComplianceReport,
|
|
175
181
|
deleteByContractorId,
|
|
@@ -27,6 +27,18 @@ const getRecordHistory = (contractorId, context) => {
|
|
|
27
27
|
return contractorsAPI.getRecordHistory(contractorId, context);
|
|
28
28
|
};
|
|
29
29
|
|
|
30
|
+
const getRecordHistoryEventReport = async (recordHistoryId, context, { expectError } = {}) => {
|
|
31
|
+
const historyEventReportResponse = await contractorsAPI.getRecordHistoryEventReport(recordHistoryId, context);
|
|
32
|
+
|
|
33
|
+
if (expectError) {
|
|
34
|
+
return historyEventReportResponse;
|
|
35
|
+
} else if (historyEventReportResponse.status !== httpResponseStatusCodes.OK) {
|
|
36
|
+
throw new Error(`Failed to get record history event report: ${historyEventReportResponse.statusText}`);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return historyEventReportResponse.data;
|
|
40
|
+
};
|
|
41
|
+
|
|
30
42
|
const getRecordOcrStatus = (recordId, context) => {
|
|
31
43
|
return contractorsAPI.getRecordOcrStatus(recordId, context);
|
|
32
44
|
};
|
|
@@ -274,11 +286,22 @@ const linkDraftRequestToAccountRecord = async (requestToLink, targetAccountRecor
|
|
|
274
286
|
}
|
|
275
287
|
};
|
|
276
288
|
|
|
289
|
+
const changeRequirementsDirectly = async (recordId, newRequirementId, context) => {
|
|
290
|
+
const recordVerificationModel = await getRecordVerificationModel(recordId, context);
|
|
291
|
+
recordVerificationModel.requirementId = newRequirementId;
|
|
292
|
+
const changeRequirementRes = await changeRequirement(recordVerificationModel, context);
|
|
293
|
+
|
|
294
|
+
if (changeRequirementRes.status !== httpResponseStatusCodes.NO_CONTENT) {
|
|
295
|
+
throw Error(`Failed to change requirement for record: ${recordId}`);
|
|
296
|
+
}
|
|
297
|
+
};
|
|
298
|
+
|
|
277
299
|
module.exports = {
|
|
278
300
|
changeRequirement,
|
|
279
301
|
getContractorsByAccountId,
|
|
280
302
|
getContractorById,
|
|
281
303
|
getRecordHistory,
|
|
304
|
+
getRecordHistoryEventReport,
|
|
282
305
|
getRecordOcrStatus,
|
|
283
306
|
getComplianceReport,
|
|
284
307
|
archiveRecord,
|
|
@@ -314,5 +337,6 @@ module.exports = {
|
|
|
314
337
|
getContractorDetailsModel,
|
|
315
338
|
getBasicDetailsById,
|
|
316
339
|
getRecordsFromInsuredName,
|
|
317
|
-
linkDraftRequestToAccountRecord
|
|
340
|
+
linkDraftRequestToAccountRecord,
|
|
341
|
+
changeRequirementsDirectly
|
|
318
342
|
};
|
|
@@ -3,6 +3,7 @@ const { backendUrl } = require('../../../../env').getEnv();
|
|
|
3
3
|
|
|
4
4
|
const Endpoints = {
|
|
5
5
|
getRelatedDocPreSignedUrl: `${backendUrl}/saas/pre-signed-url/upload/document`,
|
|
6
|
+
getCreatePolicyPreSignedUrl: `${backendUrl}/saas/pre-signed-url/upload/policy`,
|
|
6
7
|
uploadRelatedDoc: recordId => `${backendUrl}/saas/contractor/${recordId}/document`,
|
|
7
8
|
fileUpload: `${backendUrl}/file/finalize-upload`
|
|
8
9
|
};
|
|
@@ -11,6 +12,10 @@ const getRelatedDocPreSignedUrl = (formData, context) => {
|
|
|
11
12
|
return requests.postRequestHandler(Endpoints.getRelatedDocPreSignedUrl, formData, context, formData.getHeaders());
|
|
12
13
|
};
|
|
13
14
|
|
|
15
|
+
const getCreatePolicyPreSignedUrl = (formData, context) => {
|
|
16
|
+
return requests.postRequestHandler(Endpoints.getCreatePolicyPreSignedUrl, formData, context, formData.getHeaders());
|
|
17
|
+
};
|
|
18
|
+
|
|
14
19
|
const uploadFileToS3 = (preSignedUrl, file) => {
|
|
15
20
|
return requests.putRequestHandler(preSignedUrl, file);
|
|
16
21
|
};
|
|
@@ -25,6 +30,7 @@ const uploadFile = data => {
|
|
|
25
30
|
|
|
26
31
|
module.exports = {
|
|
27
32
|
getRelatedDocPreSignedUrl,
|
|
33
|
+
getCreatePolicyPreSignedUrl,
|
|
28
34
|
uploadRelatedDoc,
|
|
29
35
|
uploadFileToS3,
|
|
30
36
|
uploadFile
|
|
@@ -18,6 +18,18 @@ const getRelatedDocPreSignedUrl = (recordId, context, { filePath }) => {
|
|
|
18
18
|
return uploadFileApi.getRelatedDocPreSignedUrl(formData, context);
|
|
19
19
|
};
|
|
20
20
|
|
|
21
|
+
const getCreatePolicyPreSignedUrl = async (requestId, context, { shouldExpectError } = {}) => {
|
|
22
|
+
const formData = new FormData();
|
|
23
|
+
formData.append('requestId', requestId);
|
|
24
|
+
const policyPreSignedUrlResponse = await uploadFileApi.getCreatePolicyPreSignedUrl(formData, context);
|
|
25
|
+
|
|
26
|
+
if (policyPreSignedUrlResponse.status !== httpResponseStatusCodes.OK && !shouldExpectError) {
|
|
27
|
+
throw new Error('Failed to get policy pre-signed url');
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return policyPreSignedUrlResponse;
|
|
31
|
+
};
|
|
32
|
+
|
|
21
33
|
const uploadFileToS3 = async (preSignedUrl, filePath) => {
|
|
22
34
|
const uploadFileToS3Response = await uploadFileApi.uploadFileToS3(preSignedUrl, fs.readFileSync(filePath));
|
|
23
35
|
|
|
@@ -46,6 +58,7 @@ const uploadFile = (recordId, type, fileName) => {
|
|
|
46
58
|
};
|
|
47
59
|
|
|
48
60
|
module.exports = {
|
|
61
|
+
getCreatePolicyPreSignedUrl,
|
|
49
62
|
uploadRelatedDoc,
|
|
50
63
|
uploadFileToS3
|
|
51
64
|
};
|
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
const requests = require('../../../common/requests/apiKeyAuth/requests');
|
|
2
2
|
const { openapiUrl } = require('../../../env').getEnv();
|
|
3
|
+
const { isLocalhost } = require('../../../env');
|
|
4
|
+
|
|
5
|
+
const recordsPathSegment = isLocalhost() ? 'contractors' : 'records';
|
|
3
6
|
|
|
4
7
|
const Endpoints = {
|
|
5
8
|
copyRequirement: sourceRequirementId => `${openapiUrl}/requirement/${sourceRequirementId}/copy`,
|
|
6
9
|
getRequirementsByTabId: tabId => `${openapiUrl}/tabs/${tabId}/requirements`,
|
|
7
10
|
getRequirementsByProjectId: projectId => `${openapiUrl}/properties/${projectId}/requirements`,
|
|
8
|
-
getRequirementsList: `${openapiUrl}/requirement/all
|
|
11
|
+
getRequirementsList: `${openapiUrl}/requirement/all`,
|
|
12
|
+
changeRequirements: (requestId, newReqId) => `${openapiUrl}/${recordsPathSegment}/${requestId}/requirement/${newReqId}`
|
|
9
13
|
};
|
|
10
14
|
|
|
11
15
|
const copyRequirement = (apiKey, sourceRequirementId, newRequirementOverrides) => {
|
|
@@ -24,9 +28,14 @@ const getRequirementsList = (apiKey, params) => {
|
|
|
24
28
|
return requests.getRequestHandler(Endpoints.getRequirementsList, apiKey, params);
|
|
25
29
|
};
|
|
26
30
|
|
|
31
|
+
const changeRequirements = (apiKey, requestId, newReqId) => {
|
|
32
|
+
return requests.putRequestHandler(Endpoints.changeRequirements(requestId, newReqId), apiKey);
|
|
33
|
+
};
|
|
34
|
+
|
|
27
35
|
module.exports = {
|
|
28
36
|
copyRequirement,
|
|
29
37
|
getRequirementsByTabId,
|
|
30
38
|
getRequirementsByProjectId,
|
|
31
|
-
getRequirementsList
|
|
39
|
+
getRequirementsList,
|
|
40
|
+
changeRequirements
|
|
32
41
|
};
|