Skip to content

Commit

Permalink
Merge pull request #2099 from bcgov/feature/ALCS-2411
Browse files Browse the repository at this point in the history
Throw error if correct documents failed to generate and attach
  • Loading branch information
trslater authored Feb 3, 2025
2 parents 2191b1f + 799362d commit e35e1fb
Show file tree
Hide file tree
Showing 9 changed files with 94 additions and 125 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,9 @@ export class ApplicationSubmissionReviewService {
this.toastService.showSuccessToast('Application Review Submitted');
} catch (e) {
console.error(e);
this.toastService.showErrorToast('Failed to submit Application Review, please try again later');
this.toastService.showErrorToast(
'Failed to submit Application Review, please try again. If the problem persists, contact [email protected].',
);
} finally {
this.overlayService.hideSpinner();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,9 @@ export class ApplicationSubmissionService {
this.toastService.showSuccessToast('Application Submitted');
} catch (e) {
console.error(e);
this.toastService.showErrorToast('Failed to submit Application, please try again');
this.toastService.showErrorToast(
'Failed to submit Application, please try again. If the problem persists, contact [email protected].',
);
} finally {
this.overlayService.hideSpinner();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,9 @@ export class NoticeOfIntentSubmissionService {
this.toastService.showSuccessToast('Notice of Intent Submitted');
} catch (e) {
console.error(e);
this.toastService.showErrorToast('Failed to submit Notice of Intent, please try again');
this.toastService.showErrorToast(
'Failed to submit Notice of Intent, please try again. If the problem persists, contact [email protected].',
);
} finally {
this.overlayService.hideSpinner();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,9 @@ export class NotificationSubmissionService {
this.toastService.showSuccessToast('SRW Submitted');
} catch (e) {
console.error(e);
this.toastService.showErrorToast('Failed to submit SRW, please try again');
this.toastService.showErrorToast(
'Failed to submit SRW, please try again. If the problem persists, contact [email protected].',
);
} finally {
this.overlayService.hideSpinner();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -379,16 +379,22 @@ describe('ApplicationSubmissionService', () => {
localGovernmentUuid,
});

mockGenerateSubmissionDocumentService.generateAndAttach.mockRejectedValue(undefined);
mockAppDocService.list.mockResolvedValue([
new ApplicationDocument({
typeCode: DOCUMENT_TYPE.ORIGINAL_SUBMISSION,
}),
]);
mockApplicationService.submit.mockRejectedValue(new Error());

await expect(
service.submitToAlcs(
applicationSubmission as ValidatedApplicationSubmission,
mockUser,
),
).rejects.toMatchObject(
new BaseServiceException(`Failed to submit application: ${fileNumber}`),
);
try {
await service.submitToAlcs(applicationSubmission as ValidatedApplicationSubmission, mockUser);
} catch (err) {
await expect([
new BaseServiceException(`Failed to submit application: ${fileNumber}`),
new BaseServiceException('A document failed to generate', undefined, 'DocumentGenerationError'),
]).toContainEqual(err);
}
});

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

mockGenerateSubmissionDocumentService.generateAndAttach.mockRejectedValue(undefined);
mockAppDocService.list.mockResolvedValue([
{
typeCode: DOCUMENT_TYPE.ORIGINAL_SUBMISSION,
},
{
typeCode: DOCUMENT_TYPE.ORIGINAL_SUBMISSION,
},
] as any);
mockApplicationService.submit.mockResolvedValue(mockSubmittedApp);
await service.submitToAlcs(
mockApplication as ValidatedApplicationSubmission,
mockUser,
);

expect(mockApplicationService.submit).toBeCalledTimes(1);

expect(
mockApplicationSubmissionStatusService.setStatusDate,
).toBeCalledTimes(1);
expect(mockApplicationSubmissionStatusService.setStatusDate).toBeCalledWith(
mockApplication.uuid,
SUBMISSION_STATUS.SUBMITTED_TO_ALC,
mockSubmittedApp.dateSubmittedToAlc,
);
});

it('should submit to alcs even if document generation fails', async () => {
const applicant = 'Bruce Wayne';
const typeCode = 'fake-code';
const fileNumber = 'fake';
const localGovernmentUuid = 'fake-uuid';
const mockApplication = new ApplicationSubmission({
fileNumber,
applicant,
typeCode,
localGovernmentUuid,
status: new ApplicationSubmissionToSubmissionStatus({
statusTypeCode: 'status-code',
submissionUuid: 'fake',
}),
});

const mockSubmittedApp = new Application({
dateSubmittedToAlc: new Date(),
});
mockApplicationService.submit.mockResolvedValue(mockSubmittedApp);
mockGenerateSubmissionDocumentService.generateAndAttach.mockRejectedValue(
new Error('fake'),
);

await service.submitToAlcs(
mockApplication as ValidatedApplicationSubmission,
mockUser,
);

expect(mockApplicationService.submit).toBeCalledTimes(1);
expect(
mockGenerateSubmissionDocumentService.generateAndAttach,
).toBeCalledTimes(1);
expect(
mockGenerateSubmissionDocumentService.generateAndAttach,
).rejects.toMatchObject(new Error('fake'));
expect(
mockApplicationSubmissionStatusService.setStatusDate,
).toBeCalledTimes(1);
expect(mockApplicationSubmissionStatusService.setStatusDate).toBeCalledWith(
mockApplication.uuid,
SUBMISSION_STATUS.SUBMITTED_TO_ALC,
mockSubmittedApp.dateSubmittedToAlc,
);
});

it('should submit to alcs even if document attachment to application fails', async () => {
const applicant = 'Bruce Wayne';
const typeCode = 'fake-code';
const fileNumber = 'fake';
const localGovernmentUuid = 'fake-uuid';
const mockApplication = new ApplicationSubmission({
fileNumber,
applicant,
typeCode,
localGovernmentUuid,
status: new ApplicationSubmissionToSubmissionStatus({
statusTypeCode: 'status-code',
submissionUuid: 'fake',
}),
});

const mockSubmittedApp = new Application({
dateSubmittedToAlc: new Date(),
});

mockApplicationService.submit.mockResolvedValue(mockSubmittedApp);
mockGenerateSubmissionDocumentService.generateAndAttach.mockRejectedValue(
new Error('fake'),
);

await service.submitToAlcs(
mockApplication as ValidatedApplicationSubmission,
mockUser,
);

await new Promise((r) => setTimeout(r, 100));

expect(mockApplicationService.submit).toBeCalledTimes(1);
expect(
mockGenerateSubmissionDocumentService.generateAndAttach,
).toBeCalledTimes(1);
expect(
mockGenerateSubmissionDocumentService.generateAndAttach,
).toBeCalledWith(fileNumber, mockUser);
expect(
mockApplicationSubmissionStatusService.setStatusDate,
).toBeCalledTimes(1);
expect(mockApplicationSubmissionStatusService.setStatusDate).toBeCalledTimes(1);
expect(mockApplicationSubmissionStatusService.setStatusDate).toBeCalledWith(
mockApplication.uuid,
SUBMISSION_STATUS.SUBMITTED_TO_ALC,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,16 @@ export class ApplicationSubmissionService {
user: User,
applicationReview?: ApplicationSubmissionReview,
) {
const hasReview: boolean = !!applicationReview;
await this.generateAndAttachPdfs(application.fileNumber, user, hasReview);

const documents = await this.applicationDocumentService.list(application.fileNumber);
const submissionDocs = documents.filter((document) => document.typeCode === DOCUMENT_TYPE.ORIGINAL_SUBMISSION);

if (!((hasReview && submissionDocs.length >= 2) || (!hasReview && submissionDocs.length >= 1))) {
throw new BaseServiceException('A document failed to generate', undefined, 'DocumentGenerationError');
}

let submittedApp: Application | null = null;

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

await this.updateStatus(application, SUBMISSION_STATUS.SUBMITTED_TO_ALC, submittedApp.dateSubmittedToAlc);

this.generateAndAttachPdfs(application.fileNumber, user, !!applicationReview);
} catch (ex) {
this.logger.error(ex);
throw new BaseServiceException(`Failed to submit application: ${application.fileNumber}`);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import {
STRUCTURE_TYPES,
} from './notice-of-intent-submission.entity';
import { NoticeOfIntentSubmissionService } from './notice-of-intent-submission.service';
import { DOCUMENT_TYPE } from '../../document/document-code.entity';

describe('NoticeOfIntentSubmissionService', () => {
let service: NoticeOfIntentSubmissionService;
Expand Down Expand Up @@ -225,21 +226,38 @@ describe('NoticeOfIntentSubmissionService', () => {
localGovernmentUuid,
});

mockGenerateNoiSubmissionDocumentService.generateAndAttach.mockResolvedValue(undefined);
mockNoiDocService.list.mockResolvedValue([
new NoticeOfIntentDocument({
typeCode: DOCUMENT_TYPE.ORIGINAL_SUBMISSION,
}),
]);
mockNoiService.submit.mockRejectedValue(new Error());

await expect(
service.submitToAlcs(noticeOfIntentSubmission as ValidatedNoticeOfIntentSubmission, mockUser),
).rejects.toMatchObject(new BaseServiceException(`Failed to submit notice of intent: ${fileNumber}`));
try {
await service.submitToAlcs(noticeOfIntentSubmission as ValidatedNoticeOfIntentSubmission, mockUser);
} catch (err) {
await expect([
new BaseServiceException(`Failed to submit notice of intent: ${fileNumber}`),
new BaseServiceException('A document failed to generate', undefined, 'DocumentGenerationError'),
]).toContainEqual(err);
}
});

it('should call out to service on submitToAlcs', async () => {
const mockNoticeOfIntent = new NoticeOfIntent({
dateSubmittedToAlc: new Date(),
});

mockNoiDocService.list.mockResolvedValue([
{
typeCode: DOCUMENT_TYPE.ORIGINAL_SUBMISSION,
},
] as any);
mockNoiStatusService.setStatusDate.mockResolvedValue(new NoticeOfIntentSubmissionToSubmissionStatus());
mockGenerateNoiSubmissionDocumentService.generateAndAttach.mockResolvedValue();

mockNoiService.submit.mockResolvedValue(mockNoticeOfIntent);

await service.submitToAlcs(mockNoiSubmission as ValidatedNoticeOfIntentSubmission, mockUser);

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

it('should populate noi tags', async () => {
mockNoiDocService.list.mockResolvedValue([] as any);

const applicant = 'Bruce Wayne';
const typeCode = 'fake-code';
const fileNumber = 'fake';
Expand Down Expand Up @@ -346,6 +366,11 @@ describe('NoticeOfIntentSubmissionService', () => {
dateSubmittedToAlc: new Date(),
});
mockNoiStatusService.setStatusDate.mockResolvedValue(new NoticeOfIntentSubmissionToSubmissionStatus());
mockNoiDocService.list.mockResolvedValue([
{
typeCode: DOCUMENT_TYPE.ORIGINAL_SUBMISSION,
} as any,
]);

mockNoiService.submit.mockResolvedValue(mockNoticeOfIntent);
await service.submitToAlcs(mockNoiSubmission as ValidatedNoticeOfIntentSubmission, mockUser);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import {
PORTAL_TO_ALCS_STRUCTURE_MAP,
PORTAL_TO_ALCS_TAGS_MAP,
} from './notice-of-intent-submission.entity';
import { NoticeOfIntent } from '../../alcs/notice-of-intent/notice-of-intent.entity';

@Injectable()
export class NoticeOfIntentSubmissionService {
Expand Down Expand Up @@ -273,10 +274,21 @@ export class NoticeOfIntentSubmissionService {
}

async submitToAlcs(noticeOfIntentSubmission: ValidatedNoticeOfIntentSubmission, user: User) {
await this.generateNoiSubmissionDocumentService.generateAndAttach(noticeOfIntentSubmission.fileNumber, user);

const documents = await this.noticeOfIntentDocumentService.list(noticeOfIntentSubmission.fileNumber);
const submissionDocs = documents.filter((document) => document.typeCode === DOCUMENT_TYPE.ORIGINAL_SUBMISSION);

if (submissionDocs.length < 1) {
throw new BaseServiceException('A document failed to generate', undefined, 'DocumentGenerationError');
}

let submittedNoi: NoticeOfIntent | null = null;

try {
const tags = this.populateNoiTags(noticeOfIntentSubmission);

const submittedNoi = await this.noticeOfIntentService.submit({
submittedNoi = await this.noticeOfIntentService.submit({
fileNumber: noticeOfIntentSubmission.fileNumber,
applicant: noticeOfIntentSubmission.applicant,
localGovernmentUuid: noticeOfIntentSubmission.localGovernmentUuid,
Expand All @@ -290,14 +302,12 @@ export class NoticeOfIntentSubmissionService {
NOI_SUBMISSION_STATUS.SUBMITTED_TO_ALC,
submittedNoi.dateSubmittedToAlc,
);

await this.generateNoiSubmissionDocumentService.generateAndAttach(submittedNoi.fileNumber, user);

return submittedNoi;
} catch (ex) {
this.logger.error(ex);
throw new BaseServiceException(`Failed to submit notice of intent: ${noticeOfIntentSubmission.fileNumber}`);
}

return submittedNoi;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { NotificationSubmissionValidatorService } from './notification-submissio
import { NotificationSubmissionUpdateDto } from './notification-submission.dto';
import { NotificationSubmission } from './notification-submission.entity';
import { NotificationSubmissionService } from './notification-submission.service';
import { BaseServiceException } from '@app/common/exceptions/base.exception';

@Controller('notification-submission')
@UseGuards(PortalAuthGuard)
Expand Down Expand Up @@ -186,11 +187,9 @@ export class NotificationSubmissionController {
);

if (savedDocument) {
await this.notificationSubmissionService.sendAndRecordLTSAPackage(
submission,
savedDocument,
user,
);
await this.notificationSubmissionService.sendAndRecordLTSAPackage(submission, savedDocument, user);
} else {
throw new BaseServiceException('A document failed to generate', undefined, 'DocumentGenerationError');
}
}
}

0 comments on commit e35e1fb

Please sign in to comment.