@getjones/test-infra 3.0.0 → 3.0.1

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 (25) hide show
  1. package/.npmrc.bak +2 -0
  2. package/package.json +1 -1
  3. package/package.json.bak +30 -0
  4. package/src/common/consts/activationStatuses.js +6 -0
  5. package/src/common/consts/projectSettings.js +6 -0
  6. package/src/common/errorCodes.js +3 -0
  7. package/src/common/requests/internalAuth/requests.js +7 -7
  8. package/src/factory/records/records.js +37 -1
  9. package/src/saas/internal-api/accounts/api/emailCustomization/accounts.email.customizations.api.js +29 -0
  10. package/src/saas/internal-api/accounts/api/emailCustomization/accounts.email.customizations.service.js +61 -0
  11. package/src/saas/internal-api/accounts/index.js +3 -1
  12. package/src/saas/internal-api/coi/api/coi.api.js +8 -2
  13. package/src/saas/internal-api/coi/api/coi.service.js +5 -1
  14. package/src/saas/internal-api/contractors/api/contractors.service.js +14 -1
  15. package/src/saas/internal-api/globalRecord/api/global.record.service.js +3 -3
  16. package/src/saas/internal-api/requests/api/requests.api.js +22 -4
  17. package/src/saas/internal-api/requests/api/requests.service.js +73 -6
  18. package/src/saas/internal-api/requests/index.js +4 -2
  19. package/src/saas/internal-api/requests/models/draft.request.report.model.js +14 -0
  20. package/src/saas/internal-api/requests/models/{inner.page.request.criteria.model.js → requestListCriteriaModel.js} +2 -2
  21. package/src/saas/internal-api/requirements/api/requirements.api.js +7 -1
  22. package/src/saas/internal-api/requirements/api/requirements.service.js +12 -1
  23. package/src/saas/internal-api/users/api/tenantApp/tenant.app.service.js +6 -2
  24. package/src/saas/openapi/requests/requests.api.js +3 -3
  25. package/src/resources/virusFile.pdf +0 -0
package/.npmrc.bak ADDED
@@ -0,0 +1,2 @@
1
+ @getjones:registry=https://registry.npmjs.org/
2
+ //registry.npmjs.org/:_authToken=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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@getjones/test-infra",
3
- "version": "3.0.0",
3
+ "version": "3.0.1",
4
4
  "description": "Providing internal and openapi interface",
5
5
  "main": "src/index.js",
6
6
  "scripts": {
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "@getjones/test-infra",
3
+ "version": "3.0.0",
4
+ "description": "Providing internal and openapi interface",
5
+ "main": "src/index.js",
6
+ "scripts": {
7
+ "test": "mocha \"./tests/**/*.test.js\" --slow 3000 --timeout 10000 --exit --inlineDiffs --bail",
8
+ "eslint-fix": "eslint \"./src/**/*.js\" --fix"
9
+ },
10
+ "author": "",
11
+ "license": "ISC",
12
+ "dependencies": {
13
+ "axios": "^0.21.1",
14
+ "axios-file": "^1.0.17",
15
+ "chai": "^4.3.4",
16
+ "dotenv": "^8.2.0",
17
+ "enum": "^3.0.4",
18
+ "form-data": "^4.0.0",
19
+ "mocha": "^8.3.2"
20
+ },
21
+ "devDependencies": {
22
+ "babel-eslint": "^10.0.3",
23
+ "eslint": "^6.8.0",
24
+ "eslint-plugin-import": "^2.19.1",
25
+ "mocha-spec-json-output-reporter": "^1.1.7"
26
+ },
27
+ "directories": {
28
+ "test": "tests"
29
+ }
30
+ }
@@ -0,0 +1,6 @@
1
+ module.exports = {
2
+ ACTIVE: 'Active',
3
+ ARCHIVED: 'Archived',
4
+ DRAFT: 'Draft',
5
+ DELETED: 'Deleted'
6
+ };
@@ -0,0 +1,6 @@
1
+ module.exports = {
2
+ tenantSolution: {
3
+ on: { tenantSolution: true },
4
+ off: { tenantSolution: false }
5
+ }
6
+ };
@@ -0,0 +1,3 @@
1
+ module.exports = {
2
+ UNKNOWN: 'UNKNOWN'
3
+ };
@@ -5,12 +5,12 @@ const { crossServiceCommunicationAuthKey } = env.getEnv();
5
5
  const defaultApiKey = crossServiceCommunicationAuthKey;
6
6
 
7
7
  const getRequestHandler = (url, params = {}, headers = {}) => {
8
- enrichAuthKey(headers, defaultApiKey);
8
+ enrichAuthKey(headers);
9
9
  return requestHandler.getRequestHandler(url, headers, params);
10
10
  };
11
11
 
12
12
  const postRequestHandler = (url, body, headers = {}, params = {}) => {
13
- enrichAuthKey(headers, defaultApiKey);
13
+ enrichAuthKey(headers);
14
14
  return requestHandler.postRequestHandler(url, body, headers, params);
15
15
  };
16
16
 
@@ -20,22 +20,22 @@ const putRequestHandler = (url, body, headers = {}, params = {}) => {
20
20
  };
21
21
 
22
22
  const putFileRequestHandler = (url, fileData, headers = {}) => {
23
- enrichAuthKey(headers, defaultApiKey);
23
+ enrichAuthKey(headers);
24
24
  return requestHandler.putFileRequestHandler(url, fileData, headers);
25
25
  };
26
26
 
27
27
  const patchRequestHandler = (url, body, headers = {}) => {
28
- enrichAuthKey(headers, defaultApiKey);
28
+ enrichAuthKey(headers);
29
29
  return requestHandler.patchRequestHandler(url, body, headers);
30
30
  };
31
31
 
32
32
  const deleteRequestHandler = (url, headers = {}, params = {}, data = {}) => {
33
- enrichAuthKey(headers, defaultApiKey);
33
+ enrichAuthKey(headers);
34
34
  return requestHandler.deleteRequestHandler(url, headers, params, data);
35
35
  };
36
36
 
37
- const enrichAuthKey = (headers, apiKey) => {
38
- headers['x-jcsc-auth'] = apiKey;
37
+ const enrichAuthKey = headers => {
38
+ headers['x-jcsc-auth'] = defaultApiKey;
39
39
  };
40
40
 
41
41
  module.exports = {
@@ -11,6 +11,7 @@ const requests = require('../../saas/internal-api/requests');
11
11
 
12
12
  const { complianceStatuses, getAuditConfigByStatus } = require('../../common/utils/complianceUtil');
13
13
  const httpResponseStatusCodes = require('../../common/httpResponseStatusCodes.json');
14
+ const activationStatuses = require('../../common/consts/activationStatuses');
14
15
  const timeUtils = require('../../common/utils/timeUtils');
15
16
 
16
17
  const filePath = path.join(__dirname, '../../resources/coi/coi.pdf');
@@ -135,6 +136,40 @@ const prepareAwaitingNewCoiRecord = async (recordCompany, recordEmail, tabId, re
135
136
  const prepareUnderReviewRecord = (recordCompany, recordEmail, tabId, requirementId, context, { recordConfig } = {}) => {
136
137
  return prepareRecord(recordCompany, recordEmail, complianceStatuses.underReview, tabId, requirementId, context, { recordConfig });
137
138
  };
139
+ const prepareDraftRecord = async (recordCompany, tabId, context, { recordEmail, requirementId, uploadCoi } = {}) => {
140
+ const requestData = await requests.services.getOrCreateRequest(
141
+ context,
142
+ tabId,
143
+ requirementId,
144
+ {
145
+ inviterEmail: credentials.superUser,
146
+ email: recordEmail,
147
+ companyName: recordCompany
148
+ },
149
+ activationStatuses.DRAFT
150
+ );
151
+
152
+ if (!(requestData && requestData.id)) {
153
+ throw Error(`Failed to create record ${recordCompany}\n${requestData}`);
154
+ }
155
+
156
+ if (uploadCoi) {
157
+ const recordId = requestData.record.contractorId;
158
+
159
+ const coiUpload = await coi.utils.uploadCoi(
160
+ recordId,
161
+ filePath,
162
+ uploaderType = coi.consts.UPLOADER_TYPES.ICS,
163
+ uploaderEmail = credentials.superUser
164
+ );
165
+
166
+ if (!(coiUpload && coiUpload.name)) {
167
+ throw Error(`Failed to upload COI for record ${recordCompany}\n${coiUpload}`);
168
+ }
169
+ }
170
+
171
+ return requestData;
172
+ };
138
173
 
139
174
  module.exports = {
140
175
  prepareCompliantRecord,
@@ -143,5 +178,6 @@ module.exports = {
143
178
  prepareWaivedRecord,
144
179
  prepareAboutToExpiredRecord,
145
180
  prepareAwaitingNewCoiRecord,
146
- prepareUnderReviewRecord
181
+ prepareUnderReviewRecord,
182
+ prepareDraftRecord
147
183
  };
@@ -0,0 +1,29 @@
1
+ const requests = require('../../../../../common/requests/cookieAuth/requests');
2
+ const internalRequests = require('../../../../../common/requests/internalAuth/requests');
3
+
4
+ const { backendUrl } = require('../../../../../env').getEnv();
5
+
6
+ const Endpoints = {
7
+ getCobranding: accountId => `${backendUrl}/saas/cobranding/fetch?accountId=${accountId}`,
8
+ deleteCobranding: accountId => `${backendUrl}/saas/cobranding/archive?accountId=${accountId}`,
9
+ publishCobranding: `${backendUrl}/saas/cobranding/publish`,
10
+ getAccountsByCobrandingEmail: email => `${backendUrl}/jcsc/account/from-email/${email}`
11
+ };
12
+
13
+ const getCobranding = (accountId, context) => {
14
+ return requests.getRequestHandler(Endpoints.getCobranding(accountId), {}, context);
15
+ };
16
+
17
+ const deleteCobranding = (accountId, context) => {
18
+ return requests.deleteRequestHandler(Endpoints.deleteCobranding(accountId), context);
19
+ };
20
+
21
+ const publishCobranding = (formData, context) => {
22
+ return requests.postRequestHandler(Endpoints.publishCobranding, formData, context, formData.getHeaders());
23
+ };
24
+
25
+ const getAccountsByCobrandingEmail = email => {
26
+ return internalRequests.getRequestHandler(Endpoints.getAccountsByCobrandingEmail(email), {});
27
+ };
28
+
29
+ module.exports = { getCobranding, deleteCobranding, publishCobranding, getAccountsByCobrandingEmail };
@@ -0,0 +1,61 @@
1
+ const FormData = require('form-data');
2
+
3
+ const emailCustomizationsAPI = require('./accounts.email.customizations.api');
4
+ const httpResponseStatusCodes = require('../../../../../common/httpResponseStatusCodes.json');
5
+
6
+ const getCobranding = async (accountId, context) => {
7
+ const response = await emailCustomizationsAPI.getCobranding(accountId, context);
8
+
9
+ if (response.status !== httpResponseStatusCodes.OK) {
10
+ throw Error(`Failed to get cobranding by account id: ${accountId} - Response: ${response.status}`);
11
+ }
12
+
13
+ return response.data;
14
+ };
15
+
16
+ const deleteCobranding = async (accountId, context) => {
17
+ const response = await emailCustomizationsAPI.deleteCobranding(accountId, context);
18
+
19
+ if (response.status !== httpResponseStatusCodes.OK) {
20
+ throw Error(`Failed to delete cobranding by account id: ${accountId} - Response: ${response.status}`);
21
+ }
22
+
23
+ return response.data;
24
+ };
25
+
26
+ const publishCobranding = async (publishCobrandingModel, context) => {
27
+ const publishCobrandingStr = JSON.stringify(publishCobrandingModel);
28
+
29
+ const formData = new FormData();
30
+ // File names are passed as empty so the integration tests won't need to start handle files
31
+ // In this case the backend just take the file name from the cobrandingData object
32
+ // and doesn't check against S3. This will work as long as we won't check the content of the cobranded
33
+ // emails themselves as there there won't be images.
34
+ formData.append('file', '');
35
+ formData.append('coBrandingData', publishCobrandingStr) ;
36
+
37
+ const response = await emailCustomizationsAPI.publishCobranding(formData, context);
38
+
39
+ if (response.status !== httpResponseStatusCodes.OK) {
40
+ throw Error(`Failed to publish cobranding with from email: ${publishCobrandingModel.fromEmailAddress} - Response: ${response.status}`);
41
+ }
42
+
43
+ return response.data;
44
+ };
45
+
46
+ const getAccountsByCobrandingEmail = async email => {
47
+ const response = await emailCustomizationsAPI.getAccountsByCobrandingEmail(email);
48
+
49
+ if (response.status !== httpResponseStatusCodes.OK) {
50
+ throw Error(`Failed to get account ids by email: ${email} - Response: ${response.status}`);
51
+ }
52
+
53
+ return response.data;
54
+ };
55
+
56
+ module.exports = {
57
+ getCobranding,
58
+ deleteCobranding,
59
+ publishCobranding,
60
+ getAccountsByCobrandingEmail
61
+ };
@@ -10,11 +10,13 @@ const consts = require('./consts/consts');
10
10
  const coreService = require('./api/core/accounts.core.service');
11
11
  const openApiServices = require('./api/openapi/accounts.openapi.service');
12
12
  const settingsServices = require('./api/settings/settings.service');
13
+ const emailCustomizationService = require('./api/emailCustomization/accounts.email.customizations.service');
13
14
 
14
15
  const services = {
15
16
  core: coreService,
16
17
  openApi: openApiServices,
17
- settings: settingsServices
18
+ settings: settingsServices,
19
+ emailCustomizations: emailCustomizationService
18
20
  };
19
21
 
20
22
  module.exports = { services, models, utils, consts };
@@ -1,5 +1,6 @@
1
1
  const axiosFile = require('axios-file');
2
2
  const requests = require('../../../../common/requests/cookieAuth/requests');
3
+ const internalRequests = require('../../../../common/requests/internalAuth/requests');
3
4
 
4
5
  const { backendUrl } = require('../../../../env').getEnv();
5
6
 
@@ -7,7 +8,8 @@ const Endpoints = {
7
8
  uploadToS3: `${backendUrl}/_saas/coi/upload`,
8
9
  submitCoi: `${backendUrl}/coi/merge`,
9
10
  completeScan: contractorId => `${backendUrl}/saas/auditor/contractors/${contractorId}/coi/complete-scan`,
10
- getCoiPresignedUrl: fileName => `${backendUrl}/saas/coi/${fileName}`
11
+ getCoiPresignedUrl: fileName => `${backendUrl}/saas/coi/${fileName}`,
12
+ getCoiHashes: recordId => `${backendUrl}/jcsc/record/${recordId}/coi/hashes`
11
13
  };
12
14
 
13
15
  const uploadToS3 = (contractorId, fileData) => {
@@ -31,4 +33,8 @@ const getCoiPreSignedUrl = (coiFileName, context) => {
31
33
  return requests.getRequestHandler(Endpoints.getCoiPresignedUrl(coiFileName), {}, context);
32
34
  };
33
35
 
34
- module.exports = { uploadToS3, submitCoi, getCoiPreSignedUrl, completeScan };
36
+ const getCoiHashes = recordId => {
37
+ return internalRequests.getRequestHandler(Endpoints.getCoiHashes(recordId));
38
+ };
39
+
40
+ module.exports = { uploadToS3, submitCoi, completeScan, getCoiPreSignedUrl, getCoiHashes };
@@ -19,4 +19,8 @@ const getCoiPreSignedUrl = (coiFileName, context) => {
19
19
  return coiApi.getCoiPreSignedUrl(coiFileName, context);
20
20
  };
21
21
 
22
- module.exports = { uploadToS3, submitCoi, getCoiPreSignedUrl, completeScan };
22
+ const getCoiHashes = recordId => {
23
+ return coiApi.getCoiHashes(recordId);
24
+ };
25
+
26
+ module.exports = { uploadToS3, submitCoi, getCoiPreSignedUrl, completeScan, getCoiHashes };
@@ -6,7 +6,9 @@ const { AssignRequirementModel } = require('../models/assign.requirement.model')
6
6
  const { ContractorDetailsModel } = require('../models/edit.contractor.model');
7
7
  const httpResponseStatusCodes = require('../../../../common/httpResponseStatusCodes.json');
8
8
  const { waitFor } = require('../../../../common/utils/timeUtils');
9
+ const activationStatuses = require('../../../../common/consts/activationStatuses');
9
10
  const utils = require('../utils');
11
+ const requestService = require('../../requests/api/requests.service');
10
12
 
11
13
  const getContractorsByAccountId = async (accountId, context, activationStatus = null) => {
12
14
  if (activationStatus) {
@@ -107,7 +109,7 @@ const deleteByContractorId = (contractorId, context) => {
107
109
  return contractorsAPI.deleteByContractorId(contractorId, context);
108
110
  };
109
111
 
110
- const deleteAllRecordsInAccount = async (accountId, context, { activationStatus } = {}) => {
112
+ const deleteAllRecordsInAccount = async (accountId, context, { activationStatus = [activationStatuses.ACTIVE, activationStatuses.ARCHIVED, activationStatuses.DRAFT] } = {}) => {
111
113
  const { data: existingRecords } = await getContractorsByAccountId(accountId, context, activationStatus);
112
114
 
113
115
  if (!existingRecords.length) {
@@ -135,11 +137,20 @@ const deleteAllRecordsInAccount = async (accountId, context, { activationStatus
135
137
  }
136
138
  };
137
139
 
140
+ const deleteAllActiveRecordsInAccount = async (accountId, context) => {
141
+ return deleteAllRecordsInAccount(accountId, context, { activationStatus: [activationStatuses.ACTIVE] });
142
+ };
143
+
138
144
  const getRecordVerificationModel = async (recordId, context, { requirementId, requirementDateModified } = {}) => {
139
145
  const { data: recordData } = await getContractorById(recordId, context);
140
146
  return new RecordModifyDateVerificationModel(recordData.id, { contractorDateModified: recordData.dateModified, requirementId, requirementDateModified });
141
147
  };
142
148
 
149
+ const getRecordVerificationModelForDraftRecord = (request, { requirementId, requirementDateModified } = {}) => {
150
+ const { record } = request;
151
+ return new RecordModifyDateVerificationModel(record.id, { contractorDateModified: record.dateModified, requirementId, requirementDateModified });
152
+ };
153
+
143
154
  const getAssignRequirementModel = (requirementId, companyName, emailAddress) => {
144
155
  return new AssignRequirementModel(requirementId, companyName, emailAddress);
145
156
  };
@@ -220,7 +231,9 @@ module.exports = {
220
231
  unmuteNotifications,
221
232
  deleteByContractorId,
222
233
  deleteAllRecordsInAccount,
234
+ deleteAllActiveRecordsInAccount,
223
235
  getRecordVerificationModel,
236
+ getRecordVerificationModelForDraftRecord,
224
237
  assignRequirement,
225
238
  getAssignRequirementModel,
226
239
  getLinkedProjectsCount,
@@ -70,14 +70,14 @@ const splitToExistGlobalRecord = (recordId, glPolicyNumber, globalRecordId, cont
70
70
  return globalRecordAPI.splitToExistGlobalRecord(requestData, context);
71
71
  };
72
72
 
73
- const getGlobalRecordByRecordId = async (recordId, context) => {
73
+ const getGlobalRecordByRecordId = async (recordId, context, shouldSucceed = true) => {
74
74
  const response = await globalRecordAPI.getGlobalRecordByRecordId(recordId, context);
75
75
 
76
- if (response.status !== httpResponseStatusCodes.OK) {
76
+ if (response.status !== httpResponseStatusCodes.OK && shouldSucceed) {
77
77
  throw Error(`Failed to get global record by recordId - ${recordId}\n${response.data}`);
78
78
  }
79
79
 
80
- return response.data;
80
+ return response;
81
81
  };
82
82
 
83
83
  const dismissGlobalChanges = (id, context) => {
@@ -6,6 +6,8 @@ const Endpoints = {
6
6
  addRequestToRecord: (recordId, tabId) => `${backendUrl}/saas/${tabId}/request/${recordId}`,
7
7
  publicLinkInvite: `${backendUrl}/_saas/requests/publicinvite`,
8
8
  edit: contractorId => `${backendUrl}/saas/requests/${contractorId}/update`,
9
+ saveDraftRequest: `${backendUrl}/saas/requests/draft/save`,
10
+ activateDraftRequest: `${backendUrl}/saas/requests/draft/activate`,
9
11
  getById: requestId => `${backendUrl}/saas/request/${requestId}`,
10
12
  getAccountRequests: accountId => `${backendUrl}/saas/requests/${accountId}`,
11
13
  getByTabId: `${backendUrl}/saas/requests`,
@@ -13,7 +15,8 @@ const Endpoints = {
13
15
  `${backendUrl}/saas/requests/search?&projectId=${projectId}&searchWord=${searchWord}`,
14
16
  getAutocompleteAutoSelect: `${backendUrl}/saas/request/auto/selection`,
15
17
  getTabTenantRequestsInProject: projectId => `${backendUrl}/saas/project/${projectId}/tenants/companies`,
16
- innerPageRequests: `${backendUrl}/saas/requests/chart-filter`
18
+ innerPageRequests: `${backendUrl}/saas/requests/chart-filter`,
19
+ homePageRequests: `${backendUrl}/saas/requests/actionable`
17
20
  };
18
21
 
19
22
  const createRequest = (createRequestModel, context) => {
@@ -34,6 +37,14 @@ const editRequestAndRecordDetails = (editRequestModel, context) => {
34
37
  return requests.postRequestHandler(Endpoints.edit(contractorId), editRequestModel, context, {}, params);
35
38
  };
36
39
 
40
+ const saveDraftRequest = (draftRequestReportModel, context) => {
41
+ return requests.postRequestHandler(Endpoints.saveDraftRequest, draftRequestReportModel, context);
42
+ };
43
+
44
+ const activateDraftRequest = (draftRequestReportModel, context) => {
45
+ return requests.postRequestHandler(Endpoints.activateDraftRequest, draftRequestReportModel, context);
46
+ };
47
+
37
48
  const getRequestById = (requestId, context) => {
38
49
  return requests.getRequestHandler(Endpoints.getById(requestId), {}, context);
39
50
  };
@@ -59,8 +70,12 @@ const getTabTenantRequestsInProject = (projectId, context) => {
59
70
  return requests.getRequestHandler(Endpoints.getTabTenantRequestsInProject(projectId), {}, context);
60
71
  };
61
72
 
62
- const getInnerPageRequests = (innerPageRequestCriteriaModel, context) => {
63
- return requests.postRequestHandler(Endpoints.innerPageRequests, innerPageRequestCriteriaModel, context);
73
+ const getInnerPageRequests = (requestListCriteriaModel, context) => {
74
+ return requests.postRequestHandler(Endpoints.innerPageRequests, requestListCriteriaModel, context);
75
+ };
76
+
77
+ const getHomePageRequests = (requestListCriteriaModel, context) => {
78
+ return requests.postRequestHandler(Endpoints.homePageRequests, requestListCriteriaModel, context);
64
79
  };
65
80
 
66
81
  module.exports = {
@@ -68,11 +83,14 @@ module.exports = {
68
83
  addRequestToRecord,
69
84
  inviteRequestViaPublicLink,
70
85
  editRequestAndRecordDetails,
86
+ saveDraftRequest,
87
+ activateDraftRequest,
71
88
  getRequestById,
72
89
  getRequestsByAccountId,
73
90
  getRequestsByTabId,
74
91
  requestsGlobalSearch,
75
92
  getAutocompleteAutoSelect,
76
93
  getTabTenantRequestsInProject,
77
- getInnerPageRequests
94
+ getInnerPageRequests,
95
+ getHomePageRequests
78
96
  };
@@ -1,6 +1,7 @@
1
1
  const requestsAPI = require('./requests.api');
2
2
  const { CreateRequestModel, ContractorInfo } = require('../models/create.request.model');
3
- const { InnerPageRequestCriteriaModel } = require('../models/inner.page.request.criteria.model');
3
+ const { RequestListCriteriaModel } = require('../models/requestListCriteriaModel');
4
+ const { DraftRequestReportModel } = require('../models/draft.request.report.model');
4
5
  const { RequestModel } = require('../models/edit.request.model');
5
6
  const { validateType } = require('../../../../common/validations/typeValidations');
6
7
  const httpResponseStatusCodes = require('../../../../common/httpResponseStatusCodes.json');
@@ -24,6 +25,56 @@ const editRequestAndRecordDetails = (editRequestModel, context) => {
24
25
  return requestsAPI.editRequestAndRecordDetails(editRequestModel, context);
25
26
  };
26
27
 
28
+ const activateDraftRequest = (draftRequestReportModel, context) => {
29
+ validateType(draftRequestReportModel, DraftRequestReportModel);
30
+ return requestsAPI.activateDraftRequest(draftRequestReportModel, context);
31
+ };
32
+
33
+ const activateByRequest = async (request, context, { email, requirementId, additionalEmailList, dateModified, overrideDateModified } = {}) => {
34
+ const emailAddress = email || request.record.emailAddress;
35
+ const selectedRequirementsId = requirementId || request.record.requirementId;
36
+ const additionalEmails = additionalEmailList || request.record.additionalEmails;
37
+ const recordDateModified = dateModified || request.record.dateModified;
38
+
39
+ const draftRequestReportModel = new DraftRequestReportModel(
40
+ request.id,
41
+ {
42
+ emailAddress,
43
+ selectedRequirementsId,
44
+ additionalEmails,
45
+ recordDateModified,
46
+ overrideDateModified
47
+ }
48
+ );
49
+
50
+ return activateDraftRequest(draftRequestReportModel, context);
51
+ };
52
+
53
+ const saveDraftRequest = (draftRequestReportModel, context) => {
54
+ validateType(draftRequestReportModel, DraftRequestReportModel);
55
+ return requestsAPI.saveDraftRequest(draftRequestReportModel, context);
56
+ };
57
+
58
+ const saveDraftByRequest = async (request, context, { email, requirementId, additionalEmailList, dateModified, overrideDateModified } = {}) => {
59
+ const emailAddress = email || request.record.emailAddress;
60
+ const selectedRequirementsId = requirementId || request.record.requirementId;
61
+ const additionalEmails = additionalEmailList || request.record.additionalEmails;
62
+ const recordDateModified = dateModified || request.record.dateModified;
63
+
64
+ const draftRequestReportModel = new DraftRequestReportModel(
65
+ request.id,
66
+ {
67
+ emailAddress,
68
+ selectedRequirementsId,
69
+ additionalEmails,
70
+ recordDateModified,
71
+ overrideDateModified
72
+ }
73
+ );
74
+
75
+ return saveDraftRequest(draftRequestReportModel, context);
76
+ };
77
+
27
78
  const getAutocompleteAutoSelect = async (params, context) => {
28
79
  const { companyOrDba, tabId, requirementsId } = params;
29
80
  const autoSelectedRequest = await requestsAPI.getAutocompleteAutoSelect({ companyOrDba, tabId, requirementsId }, context);
@@ -101,16 +152,16 @@ const getTabTenantRequestsInProject = async (projectId, context) => {
101
152
  return response.data;
102
153
  };
103
154
 
104
- const getRequestFromTabByRecordId = async (recordId, tabId, context) => {
105
- const { data: requestsInTab } = await requestsAPI.getRequestsByTabId(tabId, context);
155
+ const getRequestFromTabByRecordId = async (recordId, tabId, context, activationStatus) => {
156
+ const { data: requestsInTab } = await requestsAPI.getRequestsByTabId(tabId, context, activationStatus);
106
157
  const request = requestsInTab.find(({ record }) => record.contractorId === recordId);
107
158
 
108
159
  return request;
109
160
  };
110
161
 
111
- const getInnerPageRequests = async (innerPageRequestCriteriaModel, context) => {
112
- validateType(innerPageRequestCriteriaModel, InnerPageRequestCriteriaModel);
113
- const response = await requestsAPI.getInnerPageRequests(innerPageRequestCriteriaModel, context);
162
+ const getInnerPageRequests = async (requestListCriteriaModel, context) => {
163
+ validateType(requestListCriteriaModel, RequestListCriteriaModel);
164
+ const response = await requestsAPI.getInnerPageRequests(requestListCriteriaModel, context);
114
165
 
115
166
  if (response.status !== httpResponseStatusCodes.OK) {
116
167
  throw Error(`Get requests inner page has fail\n${response}`);
@@ -119,6 +170,17 @@ const getInnerPageRequests = async (innerPageRequestCriteriaModel, context) => {
119
170
  return response.data;
120
171
  };
121
172
 
173
+ const getHomePageRequests = async (requestListCriteriaModel, context) => {
174
+ validateType(requestListCriteriaModel, RequestListCriteriaModel);
175
+ const response = await requestsAPI.getHomePageRequests(requestListCriteriaModel, context);
176
+
177
+ if (response.status !== httpResponseStatusCodes.OK) {
178
+ throw Error(`Get requests home page has fail\n${response}`);
179
+ }
180
+
181
+ return response.data;
182
+ };
183
+
122
184
  const getAllRequestsByName = async (recordName, accountId, context) => {
123
185
  const { data: requestsInAccount } = await requestsAPI.getRequestsByAccountId(accountId, context);
124
186
  const requests = requestsInAccount.filter(requests => requests.record.company === recordName);
@@ -139,6 +201,10 @@ module.exports = {
139
201
  addRequestToRecord,
140
202
  inviteRequestViaPublicLink,
141
203
  editRequestAndRecordDetails,
204
+ activateByRequest,
205
+ saveDraftRequest,
206
+ saveDraftByRequest,
207
+ activateDraftRequest,
142
208
  getRequestsByTabId,
143
209
  getRequestById,
144
210
  getRequestsByAccountId,
@@ -148,6 +214,7 @@ module.exports = {
148
214
  getTabTenantRequestsInProject,
149
215
  getRequestFromTabByRecordId,
150
216
  getInnerPageRequests,
217
+ getHomePageRequests,
151
218
  getAllRequestsByName,
152
219
  getRequestByName
153
220
  };
@@ -2,7 +2,8 @@ const services = require('./api/requests.service');
2
2
 
3
3
  const { TenantRequestModel, RequestModel, TabModel } = require('./models/edit.request.model');
4
4
  const { CreateRequestModel, ContractorInfo } = require('./models/create.request.model');
5
- const { InnerPageRequestCriteriaModel } = require('./models/inner.page.request.criteria.model');
5
+ const { RequestListCriteriaModel } = require('./models/requestListCriteriaModel');
6
+ const { DraftRequestReportModel } = require('./models/draft.request.report.model');
6
7
 
7
8
  const models = {
8
9
  TenantRequestModel,
@@ -10,7 +11,8 @@ const models = {
10
11
  TabModel,
11
12
  CreateRequestModel,
12
13
  ContractorInfo,
13
- InnerPageRequestCriteriaModel
14
+ DraftRequestReportModel,
15
+ RequestListCriteriaModel
14
16
  };
15
17
 
16
18
  module.exports = { services, models };
@@ -0,0 +1,14 @@
1
+ class DraftRequestReportModel {
2
+ constructor(requestId, { emailAddress, selectedRequirementsId, additionalEmails, recordDateModified, overrideDateModified } = {}) {
3
+ this.requestId = requestId;
4
+ this.emailAddress = emailAddress;
5
+ this.selectedRequirementsId = selectedRequirementsId;
6
+ this.additionalEmails = additionalEmails;
7
+ this.recordDateModified = recordDateModified;
8
+ this.overrideDateModified = overrideDateModified;
9
+ }
10
+ }
11
+
12
+ module.exports = {
13
+ DraftRequestReportModel
14
+ };
@@ -1,4 +1,4 @@
1
- class InnerPageRequestCriteriaModel {
1
+ class RequestListCriteriaModel {
2
2
  constructor({
3
3
  projectIds = [],
4
4
  recordTypes = [],
@@ -13,5 +13,5 @@ class InnerPageRequestCriteriaModel {
13
13
  }
14
14
 
15
15
  module.exports = {
16
- InnerPageRequestCriteriaModel
16
+ RequestListCriteriaModel
17
17
  };
@@ -7,7 +7,8 @@ const Endpoints = {
7
7
  getRequirementById: requirementId => `${backendUrl}/saas/requirement/${requirementId}`,
8
8
  update: `${backendUrl}/saas/requirement/linked/edit`,
9
9
  updateWithNotification: `${backendUrl}/saas/requirement/linked/edit/notify`,
10
- delete: requirementId => `${backendUrl}/saas/requirement/${requirementId}`
10
+ delete: requirementId => `${backendUrl}/saas/requirement/${requirementId}`,
11
+ getLinkedRecordCount: requirementId => `${backendUrl}/saas/requirement/${requirementId}/contractor-count`
11
12
  };
12
13
 
13
14
  const createRequirement = (createRequirementModel, tabId, context) => {
@@ -23,6 +24,10 @@ const getRequirementById = (requirementId, context, { isPermanentLink } = {}) =>
23
24
  return requests.getRequestHandler(Endpoints.getRequirementById(requirementId), { isPermanentLink }, context);
24
25
  };
25
26
 
27
+ const getRequirementLinkedRecordCount = async (requirementId, context, { shouldCountDraft = true } = {}) => {
28
+ return requests.getRequestHandler(Endpoints.getLinkedRecordCount(requirementId), { shouldCountDraft }, context);
29
+ };
30
+
26
31
  const updateRequirement = (updateRequirementModel, tabId, context) => {
27
32
  return requests.postRequestHandler(Endpoints.update, updateRequirementModel, context, {}, { tabId });
28
33
  };
@@ -39,6 +44,7 @@ module.exports = {
39
44
  createRequirement,
40
45
  getRequirementsByTabId,
41
46
  getRequirementById,
47
+ getRequirementLinkedRecordCount,
42
48
  updateRequirement,
43
49
  updateRequirementWithNotification,
44
50
  deleteByRequirementId
@@ -124,6 +124,16 @@ const getRequirementDateModified = async (tabId, requirementName, context) => {
124
124
  return requirementRes.dateModified;
125
125
  };
126
126
 
127
+ const getRequirementLinkedRecordCount = async (requirementId, context, { shouldCountDraft } = {}) => {
128
+ const recordCount = await requirementsAPI.getRequirementLinkedRecordCount(requirementId, context, { shouldCountDraft });
129
+
130
+ if (recordCount.status !== httpResponseStatusCodes.OK) {
131
+ throw new Error(`Failed to retrieve linked record count for requirement - ${requirementId}\n${recordCount}`);
132
+ }
133
+
134
+ return recordCount;
135
+ };
136
+
127
137
  module.exports = {
128
138
  createRequirement,
129
139
  getRequirementById,
@@ -138,5 +148,6 @@ module.exports = {
138
148
  deleteAllRequirementsInTabs,
139
149
  getCreateRequirementModel,
140
150
  getUpdatedRequirementModel,
141
- getRequirementDateModified
151
+ getRequirementDateModified,
152
+ getRequirementLinkedRecordCount
142
153
  };
@@ -41,7 +41,7 @@ const getTenantUserByEmail = async (projectId, email, context) => {
41
41
  return tenant;
42
42
  };
43
43
 
44
- const getOrCreateTenantUser = async (projectId, email, company, requestId, context, { fullName = 'Tenant User', password = credentials.strongPassword, toSignUp = true } = {}) => {
44
+ const getOrCreateTenantUser = async (projectId, email, company, requestId, context, { fullName = 'Tenant User', password = credentials.strongPassword, toSignUp = true, expectError } = {}) => {
45
45
  let tenantUser = await getTenantUserByEmail(projectId, email, context);
46
46
 
47
47
  if (tenantUser && tenantUser.subuserId && tenantUser.isVerified) {
@@ -52,7 +52,11 @@ const getOrCreateTenantUser = async (projectId, email, company, requestId, conte
52
52
  const inviteResponse = await inviteTenantUser(projectId, inviteUserModel, context);
53
53
 
54
54
  if (inviteResponse.status !== httpResponseStatusCodes.OK) {
55
- throw new Error(`Failed to invite tenant user with email: ${email}\n${inviteResponse}`);
55
+ if (expectError) {
56
+ return inviteResponse;
57
+ } else {
58
+ throw new Error(`Failed to invite tenant user with email: ${email}\n${inviteResponse}`);
59
+ }
56
60
  }
57
61
 
58
62
  tenantUser = await getTenantUserByEmail(projectId, email, context);
@@ -49,17 +49,17 @@ const updateRequest = (apiKey, id, updateRequestModel) => {
49
49
 
50
50
  const changeRequirement = (apiKey, requestId, requirementId) => {
51
51
  const endpoint = Endpoints.changeRequirement(requestId, requirementId);
52
- return requests.putRequestHandler(endpoint, apiKey);
52
+ return requests.putRequestHandler(endpoint, apiKey, {});
53
53
  };
54
54
 
55
55
  const archiveRequest = (apiKey, requestId) => {
56
56
  const endpoint = Endpoints.archive(requestId);
57
- return requests.putRequestHandler(endpoint, apiKey);
57
+ return requests.putRequestHandler(endpoint, apiKey, {});
58
58
  };
59
59
 
60
60
  const restoreRequest = (apiKey, requestId) => {
61
61
  const endpoint = Endpoints.restore(requestId);
62
- return requests.putRequestHandler(endpoint, apiKey);
62
+ return requests.putRequestHandler(endpoint, apiKey, {});
63
63
  };
64
64
 
65
65
  const deleteRequest = (apiKey, requestId) => {
Binary file