Skip to content

Commit

Permalink
Merge pull request #1145 from bcgov/feature/ALCS-1202
Browse files Browse the repository at this point in the history
Decision outcome applications,noi public search
  • Loading branch information
urmikgov authored Nov 21, 2023
2 parents 80dd877 + aa82523 commit d491cad
Show file tree
Hide file tree
Showing 17 changed files with 186 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,13 @@
</td>
</ng-container>

<ng-container matColumnDef="outcome">
<th class="type-cell" mat-header-cell *matHeaderCellDef mat-sort-header>Outcome</th>
<td mat-cell *matCellDef="let element">
{{ outcomeMapping[element.outcome] | emptyColumn }}
</td>
</ng-container>

<ng-container matColumnDef="lastUpdate">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Last Update</th>
<td mat-cell *matCellDef="let element">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { MatTableDataSource } from '@angular/material/table';
import { Router } from '@angular/router';
import { Subject, takeUntil } from 'rxjs';
import { ApplicationStatusDto } from '../../../../services/application-submission/application-submission.dto';
import { ApplicationSearchResultDto } from '../../../../services/search/search.dto';
import { ApplicationSearchResultDto, displayedColumns, outcomeMapping } from '../../../../services/search/search.dto';
import { SearchResult, TableChange } from '../search.interface';

@Component({
Expand Down Expand Up @@ -36,7 +36,9 @@ export class ApplicationSearchTableComponent implements OnDestroy {
@Input() statuses: ApplicationStatusDto[] = [];
@Output() tableChange = new EventEmitter<TableChange>();

displayedColumns = ['fileId', 'ownerName', 'type', 'portalStatus', 'lastUpdate', 'government'];
displayedColumns = displayedColumns;
outcomeMapping = outcomeMapping;

dataSource = new MatTableDataSource<SearchResult>();
pageIndex = 0;
itemsPerPage = 20;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,13 @@
</div>
</td>
</ng-container>

<ng-container matColumnDef="outcome">
<th class="type-cell" mat-header-cell *matHeaderCellDef mat-sort-header>Outcome</th>
<td mat-cell *matCellDef="let element">
{{ outcomeMapping[element.outcome] | emptyColumn }}
</td>
</ng-container>

<ng-container matColumnDef="lastUpdate">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Last Update</th>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { MatTableDataSource } from '@angular/material/table';
import { Router } from '@angular/router';
import { Subject, takeUntil } from 'rxjs';
import { ApplicationStatusDto } from '../../../../services/application-submission/application-submission.dto';
import { NoticeOfIntentSearchResultDto } from '../../../../services/search/search.dto';
import { NoticeOfIntentSearchResultDto, displayedColumns, outcomeMapping } from '../../../../services/search/search.dto';
import { SearchResult, TableChange } from '../search.interface';

@Component({
Expand Down Expand Up @@ -34,7 +34,9 @@ export class NoticeOfIntentSearchTableComponent implements OnDestroy {
@Input() statuses: ApplicationStatusDto[] = [];
@Output() tableChange = new EventEmitter<TableChange>();

displayedColumns = ['fileId', 'ownerName', 'type', 'portalStatus', 'lastUpdate', 'government'];
displayedColumns = displayedColumns;
outcomeMapping = outcomeMapping;

dataSource = new MatTableDataSource<SearchResult>();
pageIndex = 0;
itemsPerPage = 20;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,16 @@ <h3>Search by one or more of the following fields:</h3>
</mat-select>
</mat-form-field>
</div>
<div><label for="decisionOutcome">Decision Outcome</label>//TODO: Decision Outcome</div>
<div>
<label for="decisionOutcome">Decision Outcome</label>
<mat-form-field appearance="outline">
<mat-select multiple="true" id="decisionOutcome" [formControl]="portalDecisionOutcomeControl">
<mat-option *ngFor="let decision of DECISION_MAP" [value]="decision[1]">
{{ decision[0] }}
</mat-option>
</mat-select>
</mat-form-field>
</div>
<div>
<mat-label for="decisionMaker">Decision Maker</mat-label>
<mat-form-field appearance="outline">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,13 @@ const STATUS_MAP = {
'ALC Response Sent (SRW only)': 'ALCR',
};

const DECISION_MAP = {
'Approved': 'APPR',
'Refused': 'REFU',
'Rescinded': 'RESC',
'Ordered not to Proceed (NOI)': 'ONTP',
};

const SEARCH_SESSION_STORAGE_KEY = 'search';

@Component({
Expand Down Expand Up @@ -61,6 +68,7 @@ export class PublicSearchComponent implements OnInit, OnDestroy {

localGovernmentControl = new FormControl<string | undefined>(undefined);
portalStatusControl = new FormControl<string[]>([]);
portalDecisionOutcomeControl = new FormControl<string[]>([]);
componentTypeControl = new FormControl<string[] | undefined>(undefined);
pidControl = new FormControl<string | undefined>(undefined);
nameControl = new FormControl<string | undefined>(undefined);
Expand All @@ -71,6 +79,7 @@ export class PublicSearchComponent implements OnInit, OnDestroy {
pid: this.pidControl,
civicAddress: this.civicAddressControl,
portalStatus: this.portalStatusControl,
portalDecisionOutcome: this.portalDecisionOutcomeControl,
componentType: this.componentTypeControl,
government: this.localGovernmentControl,
decisionMaker: new FormControl<string | undefined>(undefined),
Expand All @@ -90,6 +99,7 @@ export class PublicSearchComponent implements OnInit, OnDestroy {
searchResultsHidden = true;
decisionMakers: DecisionMakerDto[] = [];
STATUS_MAP = Object.entries(STATUS_MAP);
DECISION_MAP = Object.entries(DECISION_MAP);
isMobile = false;
isLoading = false;
today = new Date();
Expand Down Expand Up @@ -244,6 +254,7 @@ export class PublicSearchComponent implements OnInit, OnDestroy {
fileNumber: this.formatStringSearchParam(searchControls.fileNumber.value),
name: this.formatStringSearchParam(searchControls.name.value),
civicAddress: this.formatStringSearchParam(searchControls.civicAddress.value),
decisionOutcome: searchControls.portalDecisionOutcome.value ?? undefined,
pid: this.formatStringSearchParam(searchControls.pid.value),
portalStatusCodes: searchControls.portalStatus.value ?? undefined,
governmentName: this.formatStringSearchParam(searchControls.government.value),
Expand Down Expand Up @@ -365,7 +376,7 @@ export class PublicSearchComponent implements OnInit, OnDestroy {
notifications: [],
totalApplications: 0,
totalNoticeOfIntents: 0,
totalNotifications: 0,
totalNotifications: 0
};
}

Expand Down Expand Up @@ -424,6 +435,7 @@ export class PublicSearchComponent implements OnInit, OnDestroy {
civicAddress,
government,
portalStatus,
portalDecisionOutcome
} = this.searchForm.controls;

decisionMaker.setValue(storedSearch.decisionMakerCode);
Expand All @@ -434,6 +446,7 @@ export class PublicSearchComponent implements OnInit, OnDestroy {
civicAddress.setValue(storedSearch.civicAddress);
government.setValue(storedSearch.governmentName);
portalStatus.setValue(storedSearch.portalStatusCodes ?? null);
portalDecisionOutcome.setValue(storedSearch.decisionOutcome ?? null)

if (storedSearch.dateDecidedTo) {
dateDecidedTo.setValue(new Date(storedSearch.dateDecidedTo));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
<div class="subheading2">{{ result.fileNumber }} - {{ result.ownerName }}</div>
<div [title]="result.type">{{ result.type }}</div>
<div [title]="result.localGovernmentName">{{ result.localGovernmentName }}</div>
<div>Outcome: {{ result?.outcome }}</div>
<div>Last Updated: {{ result.lastUpdate | momentFormat }}</div>
<div
*ngIf="result.status"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,6 @@ export interface SearchResult {
portalStatus?: string;
referenceId: string;
class: string;
outcome?: string;
status?: ApplicationStatusDto | NoticeOfIntentSubmissionStatusDto | NotificationSubmissionStatusDto;
}
11 changes: 11 additions & 0 deletions portal-frontend/src/app/services/search/search.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export interface BaseSearchResultDto {
localGovernmentName: string;
boardCode?: string;
ownerName: string;
outcome?: string;
dateSubmitted: number;
lastUpdate: number;
status?: string;
Expand Down Expand Up @@ -49,4 +50,14 @@ export interface SearchRequestDto extends PagingRequestDto {
dateDecidedFrom?: number;
dateDecidedTo?: number;
fileTypes: string[];
decisionOutcome?: string[];
}

export const displayedColumns = ['fileId', 'ownerName', 'type', 'portalStatus', 'outcome', 'lastUpdate', 'government'];

export const outcomeMapping: Record<string, string> = {
'APPR': "Approved",
'REFU': "Refused",
'RESC': "Rescinded",
'ONTP': "Ordered not to Proceed (NOI)"
}
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ export class Application extends Base {
@Column({
type: 'decimal',
nullable: true,
precision: 12,
precision: 15,
scale: 5,
transformer: new ColumnNumericTransformer(),
comment: 'Area in hectares of ALR impacted by the proposal',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ import { LinkedStatusType } from '../public-search.dto';
.addSelect('app_sub.type_code', 'application_type_code')
.addSelect('app.date_submitted_to_alc', 'date_submitted_to_alc')
.addSelect('app.decision_date', 'decision_date')
.addSelect('decision_date.outcome', 'outcome')
.addSelect('decision_date.dest_rank', 'dest_rank')
.addSelect('app.uuid', 'application_uuid')
.addSelect('app.region_code', 'application_region_code')
.addSelect(
Expand Down Expand Up @@ -62,9 +64,26 @@ import { LinkedStatusType } from '../public-search.dto';
(qb) =>
qb
.from(ApplicationDecision, 'decision_date')
.select('MAX("date")', 'date')
.addSelect('application_uuid', 'application_uuid')
.groupBy('application_uuid'),
.select('decisiondate', 'date')
.addSelect('outcome', 'outcome')
.addSelect('dest_rank', 'dest_rank')
.distinctOn(['application_uuid'])
.addSelect('applicationuuid', 'application_uuid')
.from(
qb
.subQuery()
.select('outcome_code', 'outcome')
.addSelect('date', 'decisiondate')
.addSelect('application_uuid', 'applicationuuid')
.addSelect(
'RANK() OVER (PARTITION BY application_uuid ORDER BY date DESC, audit_created_at DESC)',
'dest_rank',
)
.from(ApplicationDecision, 'decision')
.getQuery(),
'decisions',
)
.where('dest_rank = 1'),
'decision_date',
'decision_date."application_uuid" = app.uuid',
)
Expand Down Expand Up @@ -114,6 +133,12 @@ export class PublicApplicationSubmissionSearchView {
@ViewColumn()
decisionDate: Date | null;

@ViewColumn()
destRank: number | null;

@ViewColumn()
outcome: string | null;

@ManyToOne(() => ApplicationType, {
nullable: false,
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ export class PublicApplicationSearchService {
, "appSearch"."local_government_name"
, "appSearch"."application_type_code"
, "appSearch"."status"
, "appSearch"."outcome"
, "appSearch"."date_submitted_to_alc"
, "appSearch"."decision_date"
, "appSearch"."last_update"
Expand Down Expand Up @@ -123,6 +124,12 @@ export class PublicApplicationSearchService {
);
}

if (searchDto.decisionOutcome && searchDto.decisionOutcome.length > 0) {
query.andWhere('appSearch.outcome IN(:...outcomes)', {
outcomes: searchDto.decisionOutcome,
});
}

if (searchDto.governmentName) {
const government = await this.governmentRepository.findOneByOrFail({
name: searchDto.governmentName,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ import { LinkedStatusType } from '../public-search.dto';
.addSelect('noi_sub.type_code', 'notice_of_intent_type_code')
.addSelect('noi.date_submitted_to_alc', 'date_submitted_to_alc')
.addSelect('noi.decision_date', 'decision_date')
.addSelect('decision_date.outcome', 'outcome')
.addSelect('decision_date.dest_rank', 'dest_rank')
.addSelect('noi.uuid', 'notice_of_intent_uuid')
.addSelect('noi.region_code', 'notice_of_intent_region_code')
.addSelect(
Expand Down Expand Up @@ -62,9 +64,26 @@ import { LinkedStatusType } from '../public-search.dto';
(qb) =>
qb
.from(NoticeOfIntentDecision, 'decision_date')
.select('MAX("date")', 'date')
.addSelect('notice_of_intent_uuid', 'notice_of_intent_uuid')
.groupBy('notice_of_intent_uuid'),
.select('decisiondate', 'date')
.addSelect('outcome', 'outcome')
.addSelect('dest_rank', 'dest_rank')
.distinctOn(['notice_of_intentuuid'])
.addSelect('notice_of_intentuuid', 'notice_of_intent_uuid')
.from(
qb
.subQuery()
.select('outcome_code', 'outcome')
.addSelect('date', 'decisiondate')
.addSelect('notice_of_intent_uuid', 'notice_of_intentuuid')
.addSelect(
'RANK() OVER (PARTITION BY notice_of_intent_uuid ORDER BY date DESC, audit_created_at DESC)',
'dest_rank',
)
.from(NoticeOfIntentDecision, 'decision')
.getQuery(),
'decisions',
)
.where('dest_rank = 1'),
'decision_date',
'decision_date."notice_of_intent_uuid" = noi.uuid',
)
Expand All @@ -74,6 +93,9 @@ import { LinkedStatusType } from '../public-search.dto';
)
.andWhere(
"alcs.get_current_status_for_notice_of_intent_submission_by_uuid(noi_sub.uuid)->>'status_type_code' != 'CNCL'",
)
.andWhere(
"decision_date.dest_rank = 1",
),
})
export class PublicNoticeOfIntentSubmissionSearchView {
Expand Down Expand Up @@ -114,6 +136,12 @@ export class PublicNoticeOfIntentSubmissionSearchView {
@ViewColumn()
decisionDate: Date | null;

@ViewColumn()
destRank: number | null;

@ViewColumn()
outcome: string | null;

@ManyToOne(() => NoticeOfIntentType, {
nullable: false,
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ export class PublicNoticeOfIntentSearchService {
, "noiSearch"."status"
, "noiSearch"."date_submitted_to_alc"
, "noiSearch"."decision_date"
, "noiSearch"."outcome"
, "noiSearch"."dest_rank"
, "noiSearch"."last_update"
, "noticeOfIntentType"."audit_deleted_date_at"
, "noticeOfIntentType"."audit_created_at"
Expand Down Expand Up @@ -135,6 +137,12 @@ export class PublicNoticeOfIntentSearchService {
);
}

if (searchDto.decisionOutcome && searchDto.decisionOutcome.length > 0) {
query.andWhere('noiSearch.outcome IN(:...outcomes)', {
outcomes: searchDto.decisionOutcome,
});
}

if (searchDto.regionCodes && searchDto.regionCodes.length > 0) {
query.andWhere('noiSearch.notice_of_intent_region_code IN(:...regions)', {
regions: searchDto.regionCodes,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ export class PublicSearchController {
!searchDto.dateDecidedFrom &&
!searchDto.dateDecidedTo &&
!searchDto.decisionMakerCode &&
!searchDto.decisionOutcome &&
!isStringSetAndNotEmpty(searchDto.civicAddress);

return {
Expand Down Expand Up @@ -215,6 +216,7 @@ export class PublicSearchController {
ownerName: application.applicant,
class: 'APP',
status: application.status.status_type_code,
outcome: application.outcome ?? undefined,
};
}

Expand All @@ -231,6 +233,7 @@ export class PublicSearchController {
ownerName: noi.applicant,
class: 'NOI',
status: noi.status.status_type_code,
outcome: noi.outcome ?? undefined,
};
}

Expand Down
Loading

0 comments on commit d491cad

Please sign in to comment.