Skip to content

Commit 91ff9b8

Browse files
committed
Adapt documents component to ownership docs
- Update responsible parties to meet interface reqs for upload dialog/document list - Add certificate of title to properties - Add corporate summary to responsible parties - Update C&E docs to accept property and responsible party - Add new section for ownership docs to draft - Integrate updated docs component into new section
1 parent 2f030b3 commit 91ff9b8

28 files changed

+514
-116
lines changed

alcs-frontend/src/app/features/compliance-and-enforcement/documents/documents.component.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,7 @@ import { MatSort } from '@angular/material/sort';
55
import { MatTableDataSource } from '@angular/material/table';
66
import { FILE_NAME_TRUNCATE_LENGTH } from '../../../shared/constants';
77
import { DOCUMENT_SYSTEM } from '../../../shared/document/document.dto';
8-
import {
9-
DocumentUploadDialogData,
10-
DocumentUploadDialogOptions,
11-
} from '../../../shared/document-upload-dialog/document-upload-dialog.interface';
8+
import { DocumentUploadDialogData } from '../../../shared/document-upload-dialog/document-upload-dialog.interface';
129
import { DocumentUploadDialogComponent } from '../../../shared/document-upload-dialog/document-upload-dialog.component';
1310
import { MatDialog } from '@angular/material/dialog';
1411
import {
@@ -31,7 +28,7 @@ export class ComplianceAndEnforcementDocumentsComponent implements OnInit, OnDes
3128

3229
@Input() title?: string;
3330
@Input() fileNumber?: string;
34-
@Input() options?: DocumentUploadDialogOptions;
31+
@Input() options?: DocumentUploadDialogData;
3532
@Input() section?: Section;
3633

3734
displayedColumns: string[] = ['source', 'type', 'fileName', 'uploadedAt', 'actions'];

alcs-frontend/src/app/features/compliance-and-enforcement/draft/draft.component.html

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,18 @@ <h2>C&E File ID: {{ file?.fileNumber }}</h2>
2525
</section>
2626

2727
<section class="form-section">
28-
<app-compliance-and-enforcement-responsible-parties
28+
<app-compliance-and-enforcement-responsible-parties
2929
#responsiblePartiesComponent
3030
[fileUuid]="file?.uuid"
3131
[isPropertyCrown]="isPropertyCrown"
3232
/>
33+
<app-compliance-and-enforcement-documents
34+
#ownershipDocumentsComponent
35+
[title]="'Property Ownership Documents'"
36+
[fileNumber]="fileNumber"
37+
[options]="ownershipDocumentOptions"
38+
[section]="Section.OWNERSHIP"
39+
/>
3340
</section>
3441

3542
<div class="button-container">

alcs-frontend/src/app/features/compliance-and-enforcement/draft/draft.component.ts

Lines changed: 69 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,17 @@
11
import { AfterViewInit, Component, OnDestroy, OnInit, ViewChild } from '@angular/core';
22
import { ActivatedRoute } from '@angular/router';
3-
import { catchError, debounceTime, EMPTY, filter, firstValueFrom, skip, Subject, switchMap, takeUntil, tap } from 'rxjs';
3+
import {
4+
catchError,
5+
debounceTime,
6+
EMPTY,
7+
filter,
8+
firstValueFrom,
9+
skip,
10+
Subject,
11+
switchMap,
12+
takeUntil,
13+
tap,
14+
} from 'rxjs';
415
import { C_E_AUTOSAVE_DEBOUNCE_MS } from '../constants';
516
import {
617
ComplianceAndEnforcementDto,
@@ -17,9 +28,10 @@ import { PropertyComponent, cleanPropertyUpdate } from '../property/property.com
1728
import { ComplianceAndEnforcementPropertyDto } from '../../../services/compliance-and-enforcement/property/property.dto';
1829
import { ComplianceAndEnforcementPropertyService } from '../../../services/compliance-and-enforcement/property/property.service';
1930
import { DOCUMENT_SOURCE, DOCUMENT_TYPE } from '../../../shared/document/document.dto';
20-
import { DocumentUploadDialogOptions } from '../../../shared/document-upload-dialog/document-upload-dialog.interface';
31+
import { DocumentUploadDialogData } from '../../../shared/document-upload-dialog/document-upload-dialog.interface';
2132
import { Section } from '../../../services/compliance-and-enforcement/documents/document.service';
2233
import { ResponsiblePartiesComponent } from '../responsible-parties/responsible-parties.component';
34+
import { ResponsiblePartiesService } from '../../../services/compliance-and-enforcement/responsible-parties/responsible-parties.service';
2335

2436
@Component({
2537
selector: 'app-compliance-and-enforcement-draft',
@@ -29,7 +41,9 @@ import { ResponsiblePartiesComponent } from '../responsible-parties/responsible-
2941
export class DraftComponent implements OnInit, AfterViewInit, OnDestroy {
3042
Section = Section;
3143

32-
submissionDocumentOptions: DocumentUploadDialogOptions = {
44+
submissionDocumentOptions: DocumentUploadDialogData = {
45+
// A necessary hack to make this work without rewriting lots of code
46+
fileId: '',
3347
allowedVisibilityFlags: [],
3448
allowsFileEdit: true,
3549
allowedDocumentSources: [
@@ -42,6 +56,29 @@ export class DraftComponent implements OnInit, AfterViewInit, OnDestroy {
4256
allowedDocumentTypes: [DOCUMENT_TYPE.COMPLAINT, DOCUMENT_TYPE.REFERRAL],
4357
};
4458

59+
ownershipDocumentOptions: DocumentUploadDialogData = {
60+
// A necessary hack to make this work without rewriting lots of code
61+
fileId: '',
62+
parcelService: this.propertyService,
63+
submissionService: this.responsiblePartyService,
64+
allowedVisibilityFlags: [],
65+
allowsFileEdit: true,
66+
allowedDocumentSources: [
67+
DOCUMENT_SOURCE.PUBLIC,
68+
DOCUMENT_SOURCE.LFNG,
69+
DOCUMENT_SOURCE.BC_GOVERNMENT,
70+
DOCUMENT_SOURCE.OTHER_AGENCY,
71+
DOCUMENT_SOURCE.ALC,
72+
],
73+
defaultDocumentSource: DOCUMENT_SOURCE.ALC,
74+
allowedDocumentTypes: [
75+
DOCUMENT_TYPE.CERTIFICATE_OF_TITLE,
76+
DOCUMENT_TYPE.CORPORATE_SUMMARY,
77+
DOCUMENT_TYPE.BC_ASSESSMENT_REPORT,
78+
DOCUMENT_TYPE.SURVEY_PLAN,
79+
],
80+
};
81+
4582
$destroy = new Subject<void>();
4683

4784
fileNumber?: string;
@@ -64,6 +101,8 @@ export class DraftComponent implements OnInit, AfterViewInit, OnDestroy {
64101
private readonly complianceAndEnforcementPropertyService: ComplianceAndEnforcementPropertyService,
65102
private readonly route: ActivatedRoute,
66103
private readonly toastService: ToastService,
104+
private readonly propertyService: ComplianceAndEnforcementPropertyService,
105+
private readonly responsiblePartyService: ResponsiblePartiesService,
67106
) {}
68107

69108
ngOnInit(): void {
@@ -75,7 +114,12 @@ export class DraftComponent implements OnInit, AfterViewInit, OnDestroy {
75114
}
76115

77116
ngAfterViewInit(): void {
78-
if (!this.overviewComponent || !this.submitterComponent || !this.propertyComponent || !this.responsiblePartiesComponent) {
117+
if (
118+
!this.overviewComponent ||
119+
!this.submitterComponent ||
120+
!this.propertyComponent ||
121+
!this.responsiblePartiesComponent
122+
) {
79123
console.warn('Not all form sections component not initialized');
80124
return;
81125
}
@@ -139,18 +183,18 @@ export class DraftComponent implements OnInit, AfterViewInit, OnDestroy {
139183
switchMap((property) => {
140184
// Only auto-save if there are meaningful changes (non-empty fields)
141185
const cleanedProperty = cleanPropertyUpdate(property);
142-
186+
143187
// Check if this is a meaningful ownership type change
144188
const currentOwnership = this.property?.ownershipTypeCode || 'SMPL';
145189
const newOwnership = cleanedProperty.ownershipTypeCode;
146190
const isOwnershipChange = newOwnership !== undefined && newOwnership !== currentOwnership;
147-
191+
148192
// For non-ownership changes, check if there are other meaningful changes
149193
const propertyForCheck = { ...cleanedProperty };
150194
if (propertyForCheck.ownershipTypeCode === 'SMPL') {
151195
delete propertyForCheck.ownershipTypeCode;
152196
}
153-
197+
154198
const hasOtherActualData = Object.values(propertyForCheck).some(
155199
(value) => value !== null && value !== undefined && value !== '' && value !== 0,
156200
);
@@ -188,23 +232,19 @@ export class DraftComponent implements OnInit, AfterViewInit, OnDestroy {
188232
});
189233

190234
// Watch for property ownership changes to update Crown status
191-
this.propertyComponent.$changes
192-
.pipe(
193-
takeUntil(this.$destroy),
194-
)
195-
.subscribe(async (propertyUpdate) => {
196-
if (propertyUpdate.ownershipTypeCode) {
197-
const wasCrown = this.isPropertyCrown;
198-
this.isPropertyCrown = propertyUpdate.ownershipTypeCode === 'CRWN';
199-
200-
// If Crown status changed, update responsible parties component
201-
if (wasCrown !== this.isPropertyCrown && this.responsiblePartiesComponent) {
202-
this.responsiblePartiesComponent.isPropertyCrown = this.isPropertyCrown;
203-
204-
await this.responsiblePartiesComponent.loadResponsibleParties();
205-
}
235+
this.propertyComponent.$changes.pipe(takeUntil(this.$destroy)).subscribe(async (propertyUpdate) => {
236+
if (propertyUpdate.ownershipTypeCode) {
237+
const wasCrown = this.isPropertyCrown;
238+
this.isPropertyCrown = propertyUpdate.ownershipTypeCode === 'CRWN';
239+
240+
// If Crown status changed, update responsible parties component
241+
if (wasCrown !== this.isPropertyCrown && this.responsiblePartiesComponent) {
242+
this.responsiblePartiesComponent.isPropertyCrown = this.isPropertyCrown;
243+
244+
await this.responsiblePartiesComponent.loadResponsibleParties();
206245
}
207-
});
246+
}
247+
});
208248
}
209249

210250
async loadFile(fileNumber: string) {
@@ -216,18 +256,20 @@ export class DraftComponent implements OnInit, AfterViewInit, OnDestroy {
216256
// Load property data
217257
if (this.file.uuid) {
218258
try {
219-
this.property = await this.complianceAndEnforcementPropertyService.fetchByFileUuid(this.file.uuid);
220-
259+
const properties = await this.complianceAndEnforcementPropertyService.fetchParcels(this.file.uuid);
260+
// There should only ever be one while in draft
261+
this.property = properties[0];
262+
221263
if (this.propertyComponent && this.property) {
222264
this.propertyComponent.property = this.property;
223265
}
224266
// Check if property is Crown ownership
225267
this.isPropertyCrown = this.property?.ownershipTypeCode === 'CRWN';
226-
268+
227269
// Set the Crown status on the responsible parties component and load parties
228270
if (this.responsiblePartiesComponent) {
229271
this.responsiblePartiesComponent.isPropertyCrown = this.isPropertyCrown;
230-
// Manually trigger loading since the component's ngOnInit ran before file was loaded up
272+
// Manually trigger loading since the component's ngOnInit ran before file was loaded up
231273
if (this.file?.uuid) {
232274
this.responsiblePartiesComponent.fileUuid = this.file.uuid;
233275
await this.responsiblePartiesComponent.loadResponsibleParties();

alcs-frontend/src/app/services/compliance-and-enforcement/documents/document.dto.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,12 @@ export interface UpdateComplianceAndEnforcementDocumentDto {
1919

2020
source?: DOCUMENT_SOURCE;
2121
fileName?: string;
22-
section?: Section;
22+
23+
parcelUuid?: string;
24+
ownerUuid?: string;
2325
}
2426

2527
export interface CreateComplianceAndEnforcementDocumentDto extends UpdateComplianceAndEnforcementDocumentDto {
28+
section?: Section;
2629
file: File;
2730
}

alcs-frontend/src/app/services/compliance-and-enforcement/documents/document.service.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { HttpClient, HttpParams } from '@angular/common/http';
2-
import { Injectable } from '@angular/core';
2+
import { CSP_NONCE, Injectable } from '@angular/core';
33
import { firstValueFrom } from 'rxjs';
44
import { environment } from '../../../../environments/environment';
55
import {
@@ -12,6 +12,7 @@ import { downloadFileFromUrl, openFileInline } from '../../../shared/utils/file'
1212

1313
export enum Section {
1414
SUBMISSION = 'Submission',
15+
OWNERSHIP = 'Ownership',
1516
}
1617

1718
@Injectable({
@@ -96,6 +97,12 @@ export class ComplianceAndEnforcementDocumentService {
9697
if (dto.section) {
9798
formData.append('section', dto.section);
9899
}
100+
if (dto.parcelUuid) {
101+
formData.append('parcelUuid', dto.parcelUuid);
102+
}
103+
if (dto.ownerUuid) {
104+
formData.append('ownerUuid', dto.ownerUuid);
105+
}
99106

100107
return formData;
101108
}

alcs-frontend/src/app/services/compliance-and-enforcement/property/property.dto.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,14 @@ export interface ComplianceAndEnforcementPropertyDto {
1010
latitude: number;
1111
longitude: number;
1212
ownershipTypeCode: string;
13-
pid?: string | null;
13+
pid?: string;
1414
pin?: string | null;
1515
areaHectares: number;
1616
alrPercentage: number;
1717
alcHistory: string;
1818
localGovernment?: BaseCodeDto;
1919
ownershipType?: BaseCodeDto;
20+
certificateOfTitleUuid?: string;
2021
}
2122

2223
export interface UpdateComplianceAndEnforcementPropertyDto {
@@ -33,6 +34,7 @@ export interface UpdateComplianceAndEnforcementPropertyDto {
3334
alrPercentage?: number | null;
3435
alcHistory?: string | null;
3536
fileUuid?: string | null;
37+
certificateOfTitleUuid?: string;
3638
}
3739

3840
export interface CreateComplianceAndEnforcementPropertyDto {
@@ -49,4 +51,5 @@ export interface CreateComplianceAndEnforcementPropertyDto {
4951
alrPercentage: number;
5052
alcHistory: string;
5153
fileUuid: string;
54+
certificateOfTitleUuid?: string;
5255
}

alcs-frontend/src/app/services/compliance-and-enforcement/property/property.service.ts

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,7 @@ import { HttpClient } from '@angular/common/http';
22
import { Injectable } from '@angular/core';
33
import { firstValueFrom, Observable } from 'rxjs';
44
import { environment } from '../../../../environments/environment';
5-
import {
6-
ComplianceAndEnforcementPropertyDto,
7-
UpdateComplianceAndEnforcementPropertyDto,
8-
} from './property.dto';
5+
import { ComplianceAndEnforcementPropertyDto, UpdateComplianceAndEnforcementPropertyDto } from './property.dto';
96

107
@Injectable({
118
providedIn: 'root',
@@ -15,15 +12,11 @@ export class ComplianceAndEnforcementPropertyService {
1512

1613
constructor(private readonly http: HttpClient) {}
1714

18-
async fetchByFileUuid(fileUuid: string): Promise<ComplianceAndEnforcementPropertyDto> {
19-
return await firstValueFrom(
20-
this.http.get<ComplianceAndEnforcementPropertyDto>(`${this.url}/${fileUuid}`),
21-
);
15+
async fetchParcels(fileNumber: string): Promise<ComplianceAndEnforcementPropertyDto[]> {
16+
return await firstValueFrom(this.http.get<ComplianceAndEnforcementPropertyDto[]>(`${this.url}/${fileNumber}`));
2217
}
2318

24-
create(
25-
createDto: UpdateComplianceAndEnforcementPropertyDto,
26-
): Observable<ComplianceAndEnforcementPropertyDto> {
19+
create(createDto: UpdateComplianceAndEnforcementPropertyDto): Observable<ComplianceAndEnforcementPropertyDto> {
2720
return this.http.post<ComplianceAndEnforcementPropertyDto>(this.url, createDto);
2821
}
2922

alcs-frontend/src/app/services/compliance-and-enforcement/responsible-parties/responsible-parties.dto.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ export interface ResponsiblePartyDto {
3030
individualTelephone?: string;
3131
individualEmail?: string;
3232
individualNote?: string;
33-
33+
3434
// Organization fields
3535
organizationName?: string;
3636
organizationTelephone?: string;
@@ -68,7 +68,7 @@ export interface CreateResponsiblePartyDto {
6868
individualTelephone?: string;
6969
individualEmail?: string;
7070
individualNote?: string;
71-
71+
7272
// Organization fields
7373
organizationName?: string;
7474
organizationTelephone?: string;
@@ -91,7 +91,7 @@ export interface UpdateResponsiblePartyDto {
9191
individualTelephone?: string;
9292
individualEmail?: string;
9393
individualNote?: string;
94-
94+
9595
// Organization fields
9696
organizationName?: string;
9797
organizationTelephone?: string;

0 commit comments

Comments
 (0)