Skip to content

Commit

Permalink
Merge pull request #1729 from bcgov/feature/ALCS-1989
Browse files Browse the repository at this point in the history
Move Search Type Loading outside the view
  • Loading branch information
dhaselhan authored May 29, 2024
2 parents d150ddd + 3a60466 commit 02cfe97
Show file tree
Hide file tree
Showing 10 changed files with 232 additions and 83 deletions.
Original file line number Diff line number Diff line change
@@ -1,11 +1,4 @@
import {
DataSource,
JoinColumn,
ManyToOne,
PrimaryColumn,
ViewColumn,
ViewEntity,
} from 'typeorm';
import { DataSource, PrimaryColumn, ViewColumn, ViewEntity } from 'typeorm';
import { ApplicationDecision } from '../../../alcs/application-decision/application-decision.entity';
import { ApplicationSubmissionToSubmissionStatus } from '../../../alcs/application/application-submission-status/submission-status.entity';
import { Application } from '../../../alcs/application/application.entity';
Expand Down Expand Up @@ -43,11 +36,6 @@ import { LinkedStatusType } from '../inbox.dto';
'app.file_number = app_sub.file_number AND app.hide_from_portal = FALSE',
)
.leftJoin(User, 'user', 'user.uuid = app_sub.created_by_uuid')
.innerJoinAndSelect(
ApplicationType,
'applicationType',
'app_sub.type_code = applicationType.code',
)
.leftJoin(
(qb) =>
qb
Expand Down Expand Up @@ -105,9 +93,6 @@ export class InboxApplicationSubmissionView {
@ViewColumn()
status: LinkedStatusType;

@ManyToOne(() => ApplicationType, {
nullable: false,
})
@JoinColumn({ name: 'application_type_code' })
//Manually Joined
applicationType: ApplicationType;
}
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,6 @@ export class InboxApplicationService {

const query = this.applicationInboxRepository
.createQueryBuilder('appSearch')
.innerJoinAndMapOne(
'appSearch.applicationType',
'appSearch.applicationType',
'applicationType',
)
.orderBy('appSearch.last_update', 'DESC')
.offset((searchDto.page - 1) * searchDto.pageSize)
.limit(searchDto.pageSize);
Expand Down
31 changes: 27 additions & 4 deletions services/apps/alcs/src/portal/inbox/inbox.controller.spec.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,24 @@
import { classes } from 'automapper-classes';
import { AutomapperModule } from 'automapper-nestjs';
import { createMock, DeepMocked } from '@golevelup/nestjs-testing';
import { Test, TestingModule } from '@nestjs/testing';
import { getRepositoryToken } from '@nestjs/typeorm';
import { classes } from 'automapper-classes';
import { AutomapperModule } from 'automapper-nestjs';
import { ClsService } from 'nestjs-cls';
import { Repository } from 'typeorm';
import { mockKeyCloakProviders } from '../../../test/mocks/mockTypes';
import { ApplicationSubmissionStatusService } from '../../alcs/application/application-submission-status/application-submission-status.service';
import { ApplicationType } from '../../alcs/code/application-code/application-type/application-type.entity';
import { NoticeOfIntentSubmissionStatusService } from '../../alcs/notice-of-intent/notice-of-intent-submission-status/notice-of-intent-submission-status.service';
import { NoticeOfIntentType } from '../../alcs/notice-of-intent/notice-of-intent-type/notice-of-intent-type.entity';
import { NotificationSubmissionStatusService } from '../../alcs/notification/notification-submission-status/notification-submission-status.service';
import { NotificationType } from '../../alcs/notification/notification-type/notification-type.entity';
import { User } from '../../user/user.entity';
import { UserService } from '../../user/user.service';
import { InboxApplicationService } from './application/inbox-application.service';
import { InboxNoticeOfIntentService } from './notice-of-intent/inbox-notice-of-intent.service';
import { InboxNotificationService } from './notification/inbox-notification.service';
import { InboxController } from './inbox.controller';
import { InboxRequestDto } from './inbox.dto';
import { InboxNoticeOfIntentService } from './notice-of-intent/inbox-notice-of-intent.service';
import { InboxNotificationService } from './notification/inbox-notification.service';

describe('InboxController', () => {
let controller: InboxController;
Expand All @@ -24,6 +29,9 @@ describe('InboxController', () => {
let mockNoiSubStatusService: DeepMocked<NoticeOfIntentSubmissionStatusService>;
let mockNotiSubStatusService: DeepMocked<NotificationSubmissionStatusService>;
let mockUserService: DeepMocked<UserService>;
let mockAppTypeRepo: DeepMocked<Repository<ApplicationType>>;
let mockNOITypeRepo: DeepMocked<Repository<NoticeOfIntentType>>;
let mockNotificationTypeRepo: DeepMocked<Repository<NotificationType>>;

let mockRequest;
const mockUserId = 'fake-user-uuid';
Expand All @@ -36,6 +44,9 @@ describe('InboxController', () => {
mockNoiSubStatusService = createMock();
mockNotiSubStatusService = createMock();
mockUserService = createMock();
mockAppTypeRepo = createMock();
mockNOITypeRepo = createMock();
mockNotificationTypeRepo = createMock();

const module: TestingModule = await Test.createTestingModule({
imports: [
Expand Down Expand Up @@ -68,6 +79,18 @@ describe('InboxController', () => {
provide: NotificationSubmissionStatusService,
useValue: mockNotiSubStatusService,
},
{
provide: getRepositoryToken(ApplicationType),
useValue: mockAppTypeRepo,
},
{
provide: getRepositoryToken(NoticeOfIntentType),
useValue: mockNOITypeRepo,
},
{
provide: getRepositoryToken(NotificationType),
useValue: mockNotificationTypeRepo,
},
{
provide: ClsService,
useValue: {},
Expand Down
81 changes: 68 additions & 13 deletions services/apps/alcs/src/portal/inbox/inbox.controller.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,26 @@
import { Body, Controller, Get, Post, Req, UseGuards } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Mapper } from 'automapper-core';
import { InjectMapper } from 'automapper-nestjs';
import { Body, Controller, Get, Post, Req, UseGuards } from '@nestjs/common';
import { Repository } from 'typeorm';
import { ApplicationSubmissionStatusService } from '../../alcs/application/application-submission-status/application-submission-status.service';
import { ApplicationSubmissionStatusType } from '../../alcs/application/application-submission-status/submission-status-type.entity';
import { ApplicationStatusDto } from '../../alcs/application/application-submission-status/submission-status.dto';
import { ApplicationType } from '../../alcs/code/application-code/application-type/application-type.entity';
import { NoticeOfIntentSubmissionStatusType } from '../../alcs/notice-of-intent/notice-of-intent-submission-status/notice-of-intent-status-type.entity';
import { NoticeOfIntentStatusDto } from '../../alcs/notice-of-intent/notice-of-intent-submission-status/notice-of-intent-status.dto';
import { NoticeOfIntentSubmissionStatusService } from '../../alcs/notice-of-intent/notice-of-intent-submission-status/notice-of-intent-submission-status.service';
import { NoticeOfIntentType } from '../../alcs/notice-of-intent/notice-of-intent-type/notice-of-intent-type.entity';
import { NotificationSubmissionStatusType } from '../../alcs/notification/notification-submission-status/notification-status-type.entity';
import { NotificationStatusDto } from '../../alcs/notification/notification-submission-status/notification-status.dto';
import { NotificationSubmissionStatusService } from '../../alcs/notification/notification-submission-status/notification-submission-status.service';
import { NotificationType } from '../../alcs/notification/notification-type/notification-type.entity';
import { PortalAuthGuard } from '../../common/authorization/portal-auth-guard.service';
import { User } from '../../user/user.entity';
import { UserService } from '../../user/user.service';
import { isStringSetAndNotEmpty } from '../../utils/string-helper';
import { APPLICATION_SUBMISSION_TYPES } from '../pdf-generation/generate-submission-document.service';
import { ApplicationSearchResultDto } from '../public/search/public-search.dto';
import { InboxApplicationSubmissionView } from './application/inbox-application-view.entity';
import { InboxApplicationService } from './application/inbox-application.service';
import {
Expand Down Expand Up @@ -42,6 +48,12 @@ export class InboxController {
private noiSubStatusService: NoticeOfIntentSubmissionStatusService,
private notiSubStatusService: NotificationSubmissionStatusService,
private userService: UserService,
@InjectRepository(ApplicationType)
private appTypeRepo: Repository<ApplicationType>,
@InjectRepository(NoticeOfIntentType)
private noiTypeRepo: Repository<NoticeOfIntentType>,
@InjectRepository(NotificationType)
private notificationTypeRepo: Repository<NotificationType>,
) {}

@Get('/')
Expand Down Expand Up @@ -118,7 +130,7 @@ export class InboxController {
);
}

return this.mapSearchResults(
return await this.mapSearchResults(
applicationSearchResult,
noticeOfIntentResults,
notifications,
Expand All @@ -142,7 +154,11 @@ export class InboxController {
government?.uuid ?? null,
);

const mappedSearchResult = this.mapSearchResults(applications, null, null);
const mappedSearchResult = await this.mapSearchResults(
applications,
null,
null,
);

return {
total: mappedSearchResult.totalApplications,
Expand All @@ -168,7 +184,7 @@ export class InboxController {
government?.uuid ?? null,
);

const mappedSearchResult = this.mapSearchResults(
const mappedSearchResult = await this.mapSearchResults(
null,
noticeOfIntents,
null,
Expand Down Expand Up @@ -197,7 +213,11 @@ export class InboxController {
government?.uuid ?? null,
);

const mappedSearchResult = this.mapSearchResults(null, null, notifications);
const mappedSearchResult = await this.mapSearchResults(
null,
null,
notifications,
);

return {
total: mappedSearchResult.totalNotifications,
Expand Down Expand Up @@ -239,7 +259,7 @@ export class InboxController {
};
}

private mapSearchResults(
private async mapSearchResults(
applications: AdvancedSearchResultDto<
InboxApplicationSubmissionView[]
> | null,
Expand All @@ -252,29 +272,61 @@ export class InboxController {
) {
const response = new InboxResponseDto();

const mappedApplications: ApplicationInboxResultDto[] = [];
const mappedApplications: ApplicationSearchResultDto[] = [];
if (applications && applications.data.length > 0) {
const appTypes = await this.appTypeRepo.find({
select: {
code: true,
label: true,
},
});
const appTypeMap = new Map<string, ApplicationType>();
for (const type of appTypes) {
appTypeMap.set(type.code, type);
}
mappedApplications.push(
...applications.data.map((app) =>
this.mapApplicationToSearchResult(app),
this.mapApplicationToSearchResult(app, appTypeMap),
),
);
}

const mappedNoticeOfIntents: NoticeOfIntentInboxResultDto[] = [];
if (noticeOfIntents && noticeOfIntents.data.length > 0) {
const noiTypes = await this.noiTypeRepo.find({
select: {
code: true,
label: true,
},
});
const noiTypeMap = new Map<string, NoticeOfIntentType>();
for (const type of noiTypes) {
noiTypeMap.set(type.code, type);
}

mappedNoticeOfIntents.push(
...noticeOfIntents.data.map((noi) =>
this.mapNoticeOfIntentToSearchResult(noi),
this.mapNoticeOfIntentToSearchResult(noi, noiTypeMap),
),
);
}

const mappedNotifications: NotificationInboxResultDto[] = [];
if (notifications && notifications.data && notifications.data.length > 0) {
const notificationTypes = await this.notificationTypeRepo.find({
select: {
code: true,
label: true,
},
});
const notificationTypeMap = new Map<string, NoticeOfIntentType>();
for (const type of notificationTypes) {
notificationTypeMap.set(type.code, type);
}

mappedNotifications.push(
...notifications.data.map((notification) =>
this.mapNotificationToSearchResult(notification),
this.mapNotificationToSearchResult(notification, notificationTypeMap),
),
);
}
Expand All @@ -291,11 +343,12 @@ export class InboxController {

private mapApplicationToSearchResult(
application: InboxApplicationSubmissionView,
appTypeMap: Map<string, ApplicationType>,
): ApplicationInboxResultDto {
return {
referenceId: application.fileNumber,
fileNumber: application.fileNumber,
type: application.applicationType.label,
type: appTypeMap.get(application.applicationTypeCode)!.label,
createdAt: application.createdAt.getTime(),
lastUpdate: application.lastUpdate?.getTime(),
ownerName: application.applicant,
Expand All @@ -306,13 +359,14 @@ export class InboxController {

private mapNoticeOfIntentToSearchResult(
noi: InboxNoticeOfIntentSubmissionView,
noiTypeMap: Map<string, NoticeOfIntentType>,
): NoticeOfIntentInboxResultDto {
return {
referenceId: noi.fileNumber,
fileNumber: noi.fileNumber,
createdAt: noi.createdAt.getTime(),
lastUpdate: noi.lastUpdate?.getTime(),
type: noi.noticeOfIntentType.label,
type: noiTypeMap.get(noi.noticeOfIntentTypeCode)!.label,
ownerName: noi.applicant,
class: 'NOI',
status: noi.status.status_type_code,
Expand All @@ -321,13 +375,14 @@ export class InboxController {

private mapNotificationToSearchResult(
notification: InboxNotificationSubmissionView,
notificationTypeMap: Map<string, NotificationType>,
): NotificationInboxResultDto {
return {
referenceId: notification.fileNumber,
fileNumber: notification.fileNumber,
createdAt: notification.createdAt.getTime(),
lastUpdate: notification.status.effective_date,
type: notification.notificationType.label,
type: notificationTypeMap.get(notification.notificationTypeCode)!.label,
ownerName: notification.applicant,
class: 'NOTI',
status: notification.status.status_type_code,
Expand Down
6 changes: 6 additions & 0 deletions services/apps/alcs/src/portal/inbox/inbox.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@ import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { ApplicationSubmissionStatusModule } from '../../alcs/application/application-submission-status/application-submission-status.module';
import { Application } from '../../alcs/application/application.entity';
import { ApplicationType } from '../../alcs/code/application-code/application-type/application-type.entity';
import { LocalGovernment } from '../../alcs/local-government/local-government.entity';
import { NoticeOfIntentSubmissionStatusModule } from '../../alcs/notice-of-intent/notice-of-intent-submission-status/notice-of-intent-submission-status.module';
import { NoticeOfIntentType } from '../../alcs/notice-of-intent/notice-of-intent-type/notice-of-intent-type.entity';
import { NoticeOfIntent } from '../../alcs/notice-of-intent/notice-of-intent.entity';
import { NotificationSubmissionStatusModule } from '../../alcs/notification/notification-submission-status/notification-submission-status.module';
import { NotificationType } from '../../alcs/notification/notification-type/notification-type.entity';
import { Notification } from '../../alcs/notification/notification.entity';
import { ApplicationSubmissionReview } from '../application-submission-review/application-submission-review.entity';
import { ApplicationSubmission } from '../application-submission/application-submission.entity';
Expand All @@ -28,11 +31,14 @@ import { InboxNotificationService } from './notification/inbox-notification.serv
InboxNotificationSubmissionView,
LocalGovernment,
Application,
ApplicationType,
ApplicationSubmission,
ApplicationSubmissionReview,
NoticeOfIntent,
NoticeOfIntentType,
NoticeOfIntentSubmission,
Notification,
NotificationType,
NotificationSubmission,
]),
RedisModule,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,4 @@
import {
DataSource,
JoinColumn,
ManyToOne,
PrimaryColumn,
ViewColumn,
ViewEntity,
} from 'typeorm';
import { DataSource, PrimaryColumn, ViewColumn, ViewEntity } from 'typeorm';
import { NoticeOfIntentDecision } from '../../../alcs/notice-of-intent-decision/notice-of-intent-decision.entity';
import { NoticeOfIntentSubmissionToSubmissionStatus } from '../../../alcs/notice-of-intent/notice-of-intent-submission-status/notice-of-intent-status.entity';
import { NoticeOfIntentType } from '../../../alcs/notice-of-intent/notice-of-intent-type/notice-of-intent-type.entity';
Expand Down Expand Up @@ -43,11 +36,6 @@ import { LinkedStatusType } from '../inbox.dto';
'noi.file_number = noi_sub.file_number AND noi.hide_from_portal = false',
)
.leftJoin(User, 'user', 'user.uuid = noi_sub.created_by_uuid')
.innerJoinAndSelect(
NoticeOfIntentType,
'noticeOfIntentType',
'noi_sub.type_code = noticeOfIntentType.code',
)
.leftJoin(
(qb) =>
qb
Expand Down Expand Up @@ -108,9 +96,6 @@ export class InboxNoticeOfIntentSubmissionView {
@ViewColumn()
status: LinkedStatusType;

@ManyToOne(() => NoticeOfIntentType, {
nullable: false,
})
@JoinColumn({ name: 'notice_of_intent_type_code' })
//Manually Joined
noticeOfIntentType: NoticeOfIntentType;
}
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,6 @@ export class InboxNoticeOfIntentService {

const query = this.noiSearchRepository
.createQueryBuilder('noiSearch')
.innerJoinAndMapOne(
'noiSearch.noticeOfIntentType',
'noiSearch.noticeOfIntentType',
'noticeOfIntentType',
)
.orderBy('"noiSearch"."last_update"', 'DESC')
.offset((searchDto.page - 1) * searchDto.pageSize)
.limit(searchDto.pageSize);
Expand Down
Loading

0 comments on commit 02cfe97

Please sign in to comment.