Skip to content

Commit e35e1fb

Browse files
authored
Merge pull request #2099 from bcgov/feature/ALCS-2411
Throw error if correct documents failed to generate and attach
2 parents 2191b1f + 799362d commit e35e1fb

File tree

9 files changed

+94
-125
lines changed

9 files changed

+94
-125
lines changed

portal-frontend/src/app/services/application-submission-review/application-submission-review.service.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,9 @@ export class ApplicationSubmissionReviewService {
7878
this.toastService.showSuccessToast('Application Review Submitted');
7979
} catch (e) {
8080
console.error(e);
81-
this.toastService.showErrorToast('Failed to submit Application Review, please try again later');
81+
this.toastService.showErrorToast(
82+
'Failed to submit Application Review, please try again. If the problem persists, contact [email protected].',
83+
);
8284
} finally {
8385
this.overlayService.hideSpinner();
8486
}

portal-frontend/src/app/services/application-submission/application-submission.service.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,9 @@ export class ApplicationSubmissionService {
113113
this.toastService.showSuccessToast('Application Submitted');
114114
} catch (e) {
115115
console.error(e);
116-
this.toastService.showErrorToast('Failed to submit Application, please try again');
116+
this.toastService.showErrorToast(
117+
'Failed to submit Application, please try again. If the problem persists, contact [email protected].',
118+
);
117119
} finally {
118120
this.overlayService.hideSpinner();
119121
}

portal-frontend/src/app/services/notice-of-intent-submission/notice-of-intent-submission.service.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,9 @@ export class NoticeOfIntentSubmissionService {
114114
this.toastService.showSuccessToast('Notice of Intent Submitted');
115115
} catch (e) {
116116
console.error(e);
117-
this.toastService.showErrorToast('Failed to submit Notice of Intent, please try again');
117+
this.toastService.showErrorToast(
118+
'Failed to submit Notice of Intent, please try again. If the problem persists, contact [email protected].',
119+
);
118120
} finally {
119121
this.overlayService.hideSpinner();
120122
}

portal-frontend/src/app/services/notification-submission/notification-submission.service.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,9 @@ export class NotificationSubmissionService {
108108
this.toastService.showSuccessToast('SRW Submitted');
109109
} catch (e) {
110110
console.error(e);
111-
this.toastService.showErrorToast('Failed to submit SRW, please try again');
111+
this.toastService.showErrorToast(
112+
'Failed to submit SRW, please try again. If the problem persists, contact [email protected].',
113+
);
112114
} finally {
113115
this.overlayService.hideSpinner();
114116
}

services/apps/alcs/src/portal/application-submission/application-submission.service.spec.ts

+24-105
Original file line numberDiff line numberDiff line change
@@ -379,16 +379,22 @@ describe('ApplicationSubmissionService', () => {
379379
localGovernmentUuid,
380380
});
381381

382+
mockGenerateSubmissionDocumentService.generateAndAttach.mockRejectedValue(undefined);
383+
mockAppDocService.list.mockResolvedValue([
384+
new ApplicationDocument({
385+
typeCode: DOCUMENT_TYPE.ORIGINAL_SUBMISSION,
386+
}),
387+
]);
382388
mockApplicationService.submit.mockRejectedValue(new Error());
383389

384-
await expect(
385-
service.submitToAlcs(
386-
applicationSubmission as ValidatedApplicationSubmission,
387-
mockUser,
388-
),
389-
).rejects.toMatchObject(
390-
new BaseServiceException(`Failed to submit application: ${fileNumber}`),
391-
);
390+
try {
391+
await service.submitToAlcs(applicationSubmission as ValidatedApplicationSubmission, mockUser);
392+
} catch (err) {
393+
await expect([
394+
new BaseServiceException(`Failed to submit application: ${fileNumber}`),
395+
new BaseServiceException('A document failed to generate', undefined, 'DocumentGenerationError'),
396+
]).toContainEqual(err);
397+
}
392398
});
393399

394400
it('should call out to service on submitToAlcs', async () => {
@@ -410,112 +416,25 @@ describe('ApplicationSubmissionService', () => {
410416
dateSubmittedToAlc: new Date(),
411417
});
412418

419+
mockGenerateSubmissionDocumentService.generateAndAttach.mockRejectedValue(undefined);
420+
mockAppDocService.list.mockResolvedValue([
421+
{
422+
typeCode: DOCUMENT_TYPE.ORIGINAL_SUBMISSION,
423+
},
424+
{
425+
typeCode: DOCUMENT_TYPE.ORIGINAL_SUBMISSION,
426+
},
427+
] as any);
413428
mockApplicationService.submit.mockResolvedValue(mockSubmittedApp);
414-
await service.submitToAlcs(
415-
mockApplication as ValidatedApplicationSubmission,
416-
mockUser,
417-
);
418-
419-
expect(mockApplicationService.submit).toBeCalledTimes(1);
420-
421-
expect(
422-
mockApplicationSubmissionStatusService.setStatusDate,
423-
).toBeCalledTimes(1);
424-
expect(mockApplicationSubmissionStatusService.setStatusDate).toBeCalledWith(
425-
mockApplication.uuid,
426-
SUBMISSION_STATUS.SUBMITTED_TO_ALC,
427-
mockSubmittedApp.dateSubmittedToAlc,
428-
);
429-
});
430-
431-
it('should submit to alcs even if document generation fails', async () => {
432-
const applicant = 'Bruce Wayne';
433-
const typeCode = 'fake-code';
434-
const fileNumber = 'fake';
435-
const localGovernmentUuid = 'fake-uuid';
436-
const mockApplication = new ApplicationSubmission({
437-
fileNumber,
438-
applicant,
439-
typeCode,
440-
localGovernmentUuid,
441-
status: new ApplicationSubmissionToSubmissionStatus({
442-
statusTypeCode: 'status-code',
443-
submissionUuid: 'fake',
444-
}),
445-
});
446-
447-
const mockSubmittedApp = new Application({
448-
dateSubmittedToAlc: new Date(),
449-
});
450-
mockApplicationService.submit.mockResolvedValue(mockSubmittedApp);
451-
mockGenerateSubmissionDocumentService.generateAndAttach.mockRejectedValue(
452-
new Error('fake'),
453-
);
454429

455430
await service.submitToAlcs(
456431
mockApplication as ValidatedApplicationSubmission,
457432
mockUser,
458433
);
459434

460435
expect(mockApplicationService.submit).toBeCalledTimes(1);
461-
expect(
462-
mockGenerateSubmissionDocumentService.generateAndAttach,
463-
).toBeCalledTimes(1);
464-
expect(
465-
mockGenerateSubmissionDocumentService.generateAndAttach,
466-
).rejects.toMatchObject(new Error('fake'));
467-
expect(
468-
mockApplicationSubmissionStatusService.setStatusDate,
469-
).toBeCalledTimes(1);
470-
expect(mockApplicationSubmissionStatusService.setStatusDate).toBeCalledWith(
471-
mockApplication.uuid,
472-
SUBMISSION_STATUS.SUBMITTED_TO_ALC,
473-
mockSubmittedApp.dateSubmittedToAlc,
474-
);
475-
});
476-
477-
it('should submit to alcs even if document attachment to application fails', async () => {
478-
const applicant = 'Bruce Wayne';
479-
const typeCode = 'fake-code';
480-
const fileNumber = 'fake';
481-
const localGovernmentUuid = 'fake-uuid';
482-
const mockApplication = new ApplicationSubmission({
483-
fileNumber,
484-
applicant,
485-
typeCode,
486-
localGovernmentUuid,
487-
status: new ApplicationSubmissionToSubmissionStatus({
488-
statusTypeCode: 'status-code',
489-
submissionUuid: 'fake',
490-
}),
491-
});
492-
493-
const mockSubmittedApp = new Application({
494-
dateSubmittedToAlc: new Date(),
495-
});
496-
497-
mockApplicationService.submit.mockResolvedValue(mockSubmittedApp);
498-
mockGenerateSubmissionDocumentService.generateAndAttach.mockRejectedValue(
499-
new Error('fake'),
500-
);
501436

502-
await service.submitToAlcs(
503-
mockApplication as ValidatedApplicationSubmission,
504-
mockUser,
505-
);
506-
507-
await new Promise((r) => setTimeout(r, 100));
508-
509-
expect(mockApplicationService.submit).toBeCalledTimes(1);
510-
expect(
511-
mockGenerateSubmissionDocumentService.generateAndAttach,
512-
).toBeCalledTimes(1);
513-
expect(
514-
mockGenerateSubmissionDocumentService.generateAndAttach,
515-
).toBeCalledWith(fileNumber, mockUser);
516-
expect(
517-
mockApplicationSubmissionStatusService.setStatusDate,
518-
).toBeCalledTimes(1);
437+
expect(mockApplicationSubmissionStatusService.setStatusDate).toBeCalledTimes(1);
519438
expect(mockApplicationSubmissionStatusService.setStatusDate).toBeCalledWith(
520439
mockApplication.uuid,
521440
SUBMISSION_STATUS.SUBMITTED_TO_ALC,

services/apps/alcs/src/portal/application-submission/application-submission.service.ts

+10-2
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,16 @@ export class ApplicationSubmissionService {
231231
user: User,
232232
applicationReview?: ApplicationSubmissionReview,
233233
) {
234+
const hasReview: boolean = !!applicationReview;
235+
await this.generateAndAttachPdfs(application.fileNumber, user, hasReview);
236+
237+
const documents = await this.applicationDocumentService.list(application.fileNumber);
238+
const submissionDocs = documents.filter((document) => document.typeCode === DOCUMENT_TYPE.ORIGINAL_SUBMISSION);
239+
240+
if (!((hasReview && submissionDocs.length >= 2) || (!hasReview && submissionDocs.length >= 1))) {
241+
throw new BaseServiceException('A document failed to generate', undefined, 'DocumentGenerationError');
242+
}
243+
234244
let submittedApp: Application | null = null;
235245

236246
const shouldCreateCard = applicationReview?.isAuthorized ?? true;
@@ -247,8 +257,6 @@ export class ApplicationSubmissionService {
247257
);
248258

249259
await this.updateStatus(application, SUBMISSION_STATUS.SUBMITTED_TO_ALC, submittedApp.dateSubmittedToAlc);
250-
251-
this.generateAndAttachPdfs(application.fileNumber, user, !!applicationReview);
252260
} catch (ex) {
253261
this.logger.error(ex);
254262
throw new BaseServiceException(`Failed to submit application: ${application.fileNumber}`);

services/apps/alcs/src/portal/notice-of-intent-submission/notice-of-intent-submission.service.spec.ts

+29-4
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import {
2929
STRUCTURE_TYPES,
3030
} from './notice-of-intent-submission.entity';
3131
import { NoticeOfIntentSubmissionService } from './notice-of-intent-submission.service';
32+
import { DOCUMENT_TYPE } from '../../document/document-code.entity';
3233

3334
describe('NoticeOfIntentSubmissionService', () => {
3435
let service: NoticeOfIntentSubmissionService;
@@ -225,21 +226,38 @@ describe('NoticeOfIntentSubmissionService', () => {
225226
localGovernmentUuid,
226227
});
227228

229+
mockGenerateNoiSubmissionDocumentService.generateAndAttach.mockResolvedValue(undefined);
230+
mockNoiDocService.list.mockResolvedValue([
231+
new NoticeOfIntentDocument({
232+
typeCode: DOCUMENT_TYPE.ORIGINAL_SUBMISSION,
233+
}),
234+
]);
228235
mockNoiService.submit.mockRejectedValue(new Error());
229236

230-
await expect(
231-
service.submitToAlcs(noticeOfIntentSubmission as ValidatedNoticeOfIntentSubmission, mockUser),
232-
).rejects.toMatchObject(new BaseServiceException(`Failed to submit notice of intent: ${fileNumber}`));
237+
try {
238+
await service.submitToAlcs(noticeOfIntentSubmission as ValidatedNoticeOfIntentSubmission, mockUser);
239+
} catch (err) {
240+
await expect([
241+
new BaseServiceException(`Failed to submit notice of intent: ${fileNumber}`),
242+
new BaseServiceException('A document failed to generate', undefined, 'DocumentGenerationError'),
243+
]).toContainEqual(err);
244+
}
233245
});
234246

235247
it('should call out to service on submitToAlcs', async () => {
236248
const mockNoticeOfIntent = new NoticeOfIntent({
237249
dateSubmittedToAlc: new Date(),
238250
});
251+
252+
mockNoiDocService.list.mockResolvedValue([
253+
{
254+
typeCode: DOCUMENT_TYPE.ORIGINAL_SUBMISSION,
255+
},
256+
] as any);
239257
mockNoiStatusService.setStatusDate.mockResolvedValue(new NoticeOfIntentSubmissionToSubmissionStatus());
240258
mockGenerateNoiSubmissionDocumentService.generateAndAttach.mockResolvedValue();
241-
242259
mockNoiService.submit.mockResolvedValue(mockNoticeOfIntent);
260+
243261
await service.submitToAlcs(mockNoiSubmission as ValidatedNoticeOfIntentSubmission, mockUser);
244262

245263
expect(mockNoiService.submit).toBeCalledTimes(1);
@@ -310,6 +328,8 @@ describe('NoticeOfIntentSubmissionService', () => {
310328
});
311329

312330
it('should populate noi tags', async () => {
331+
mockNoiDocService.list.mockResolvedValue([] as any);
332+
313333
const applicant = 'Bruce Wayne';
314334
const typeCode = 'fake-code';
315335
const fileNumber = 'fake';
@@ -346,6 +366,11 @@ describe('NoticeOfIntentSubmissionService', () => {
346366
dateSubmittedToAlc: new Date(),
347367
});
348368
mockNoiStatusService.setStatusDate.mockResolvedValue(new NoticeOfIntentSubmissionToSubmissionStatus());
369+
mockNoiDocService.list.mockResolvedValue([
370+
{
371+
typeCode: DOCUMENT_TYPE.ORIGINAL_SUBMISSION,
372+
} as any,
373+
]);
349374

350375
mockNoiService.submit.mockResolvedValue(mockNoticeOfIntent);
351376
await service.submitToAlcs(mockNoiSubmission as ValidatedNoticeOfIntentSubmission, mockUser);

services/apps/alcs/src/portal/notice-of-intent-submission/notice-of-intent-submission.service.ts

+15-5
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import {
3030
PORTAL_TO_ALCS_STRUCTURE_MAP,
3131
PORTAL_TO_ALCS_TAGS_MAP,
3232
} from './notice-of-intent-submission.entity';
33+
import { NoticeOfIntent } from '../../alcs/notice-of-intent/notice-of-intent.entity';
3334

3435
@Injectable()
3536
export class NoticeOfIntentSubmissionService {
@@ -273,10 +274,21 @@ export class NoticeOfIntentSubmissionService {
273274
}
274275

275276
async submitToAlcs(noticeOfIntentSubmission: ValidatedNoticeOfIntentSubmission, user: User) {
277+
await this.generateNoiSubmissionDocumentService.generateAndAttach(noticeOfIntentSubmission.fileNumber, user);
278+
279+
const documents = await this.noticeOfIntentDocumentService.list(noticeOfIntentSubmission.fileNumber);
280+
const submissionDocs = documents.filter((document) => document.typeCode === DOCUMENT_TYPE.ORIGINAL_SUBMISSION);
281+
282+
if (submissionDocs.length < 1) {
283+
throw new BaseServiceException('A document failed to generate', undefined, 'DocumentGenerationError');
284+
}
285+
286+
let submittedNoi: NoticeOfIntent | null = null;
287+
276288
try {
277289
const tags = this.populateNoiTags(noticeOfIntentSubmission);
278290

279-
const submittedNoi = await this.noticeOfIntentService.submit({
291+
submittedNoi = await this.noticeOfIntentService.submit({
280292
fileNumber: noticeOfIntentSubmission.fileNumber,
281293
applicant: noticeOfIntentSubmission.applicant,
282294
localGovernmentUuid: noticeOfIntentSubmission.localGovernmentUuid,
@@ -290,14 +302,12 @@ export class NoticeOfIntentSubmissionService {
290302
NOI_SUBMISSION_STATUS.SUBMITTED_TO_ALC,
291303
submittedNoi.dateSubmittedToAlc,
292304
);
293-
294-
await this.generateNoiSubmissionDocumentService.generateAndAttach(submittedNoi.fileNumber, user);
295-
296-
return submittedNoi;
297305
} catch (ex) {
298306
this.logger.error(ex);
299307
throw new BaseServiceException(`Failed to submit notice of intent: ${noticeOfIntentSubmission.fileNumber}`);
300308
}
309+
310+
return submittedNoi;
301311
}
302312

303313
/**

services/apps/alcs/src/portal/notification-submission/notification-submission.controller.ts

+4-5
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import { NotificationSubmissionValidatorService } from './notification-submissio
2020
import { NotificationSubmissionUpdateDto } from './notification-submission.dto';
2121
import { NotificationSubmission } from './notification-submission.entity';
2222
import { NotificationSubmissionService } from './notification-submission.service';
23+
import { BaseServiceException } from '@app/common/exceptions/base.exception';
2324

2425
@Controller('notification-submission')
2526
@UseGuards(PortalAuthGuard)
@@ -186,11 +187,9 @@ export class NotificationSubmissionController {
186187
);
187188

188189
if (savedDocument) {
189-
await this.notificationSubmissionService.sendAndRecordLTSAPackage(
190-
submission,
191-
savedDocument,
192-
user,
193-
);
190+
await this.notificationSubmissionService.sendAndRecordLTSAPackage(submission, savedDocument, user);
191+
} else {
192+
throw new BaseServiceException('A document failed to generate', undefined, 'DocumentGenerationError');
194193
}
195194
}
196195
}

0 commit comments

Comments
 (0)