@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.
Files changed (33) hide show
  1. package/package.json +1 -1
  2. package/src/common/commonFlows/records/records.js +35 -3
  3. package/src/common/consts/s3FileTypes.js +2 -1
  4. package/src/common/utils/complianceUtil.js +3 -1
  5. package/src/defaults/configs/auditConfigs.js +25 -0
  6. package/src/defaults/configs/polices.js +6 -1
  7. package/src/factory/records/records.js +18 -13
  8. package/src/resources/coi/coi2.pdf +0 -0
  9. package/src/resources/policy/policy.pdf +0 -0
  10. package/src/resources/virusFile.pdf +0 -0
  11. package/src/saas/internal-api/accountDirectory/api/accountDirectory.api.js +32 -2
  12. package/src/saas/internal-api/accountDirectory/api/accountDirectory.service.js +131 -5
  13. package/src/saas/internal-api/accountDirectory/models/accountDirectory.model.js +18 -3
  14. package/src/saas/internal-api/agreement/api/agreement.api.js +8 -2
  15. package/src/saas/internal-api/agreement/api/agreement.service.js +13 -1
  16. package/src/saas/internal-api/coi/api/coi.api.js +7 -2
  17. package/src/saas/internal-api/coi/api/coi.service.js +14 -1
  18. package/src/saas/internal-api/coi/models/Combine.last.two.cois.model.js +25 -0
  19. package/src/saas/internal-api/coi/utils/utils.js +48 -1
  20. package/src/saas/internal-api/compliance/api/audit/audit.api.js +14 -2
  21. package/src/saas/internal-api/compliance/api/audit/audit.service.js +47 -4
  22. package/src/saas/internal-api/compliance/api/overrideGap/override.gap.api.js +7 -2
  23. package/src/saas/internal-api/compliance/api/overrideGap/override.gap.service.js +62 -21
  24. package/src/saas/internal-api/compliance/consts/audit.js +8 -2
  25. package/src/saas/internal-api/compliance/models/audit/audit.model.js +2 -1
  26. package/src/saas/internal-api/compliance/utils/auditUtil.js +35 -3
  27. package/src/saas/internal-api/contractors/api/contractors.api.js +6 -0
  28. package/src/saas/internal-api/contractors/api/contractors.service.js +25 -1
  29. package/src/saas/internal-api/uploadFiles/api/upload.file.api.js +6 -0
  30. package/src/saas/internal-api/uploadFiles/api/upload.file.service.js +13 -0
  31. package/src/saas/openapi/coi/coi.service.js +0 -1
  32. package/src/saas/openapi/requirements/requirements.api.js +11 -2
  33. 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 enterAudit = (contractorId, context) => {
39
- return auditApi.enterAudit(contractorId, context);
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
- module.exports = { waive, retract, overrideGap, retractOverride };
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 getWaiveModel = (
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 auditId = getPolicyAuditIdFromRecord(record, policyName, auditUtil.getAttributeKey(attributeName));
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 waiveModel = new WaiveRequestModel({
47
- contractorId: record.id,
48
- auditId,
49
- waiverReason,
50
- remarks,
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 = getPolicyAuditIdFromRecord(record, policyName, auditUtil.getAttributeKey(attributeName));
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 getPolicyAuditIdFromRecord = (record, policyName, attributeName) => {
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 attribute = policy.errorList.find(error => error.limitname === attributeName);
116
+ const attributes = policy.errorList.filter(error => error.limitname === attributeName);
97
117
 
98
- if (!attribute) {
118
+ if (!attributes.length) {
99
119
  throw new Error(`Attribute name: ${attributeName} don't exist in record`);
100
120
  }
101
121
 
102
- return attribute.auditId;
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
- const allWaivablePolicies = auditUtil.getAllWaivablePolicies(record, context);
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 waiveModel = getWaiveModel(record, waivable.policyName, waivable.attributeName, reason, note);
111
- const waiveResponse = await overrideGap({ waiveRequestModel: waiveModel, context });
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
- if (waiveResponse.status !== httpResponseStatusCodes.OK) {
114
- throw Error(`Failed to waive ${waivable.policyName} - ${waivable.attributeName} for ${record.company}`);
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: '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
- selection.value = config[field][1]; // Ok to be undefined
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 auditEntityModel = new auditModels.AuditEntityModel(policyId, attributeName, status, value);
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,5 +1,4 @@
1
1
  const fs = require('fs');
2
- const path = require('path');
3
2
 
4
3
  const coiApis = require('./coi.api');
5
4
  const httpResponseStatusCodes = require('../../../common/httpResponseStatusCodes.json');
@@ -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
  };