Skip to content

Commit

Permalink
Fixes validation, allow to modify geometry
Browse files Browse the repository at this point in the history
  • Loading branch information
geertplaisier committed Apr 26, 2024
1 parent fc40c95 commit ba85f67
Show file tree
Hide file tree
Showing 11 changed files with 446 additions and 268 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { PlanregistratieModel } from '../models';

export class PlanValidationHelper {

public static validatePlan(planRegistratie: PlanregistratieModel) {
if (
PlanValidationHelper.hasInvalidValue(planRegistratie.Vertrouwelijkheid)
|| PlanValidationHelper.hasInvalidValue(planRegistratie.Opdrachtgever_Type)
|| PlanValidationHelper.hasInvalidValue(planRegistratie.Jaar_Start_Project)
|| PlanValidationHelper.hasInvalidValue(planRegistratie.Oplevering_Eerste)
|| PlanValidationHelper.hasInvalidValue(planRegistratie.Oplevering_Laatste)
|| PlanValidationHelper.hasInvalidValue(planRegistratie.Plantype)
|| PlanValidationHelper.hasInvalidValue(planRegistratie.Status_Project)
|| PlanValidationHelper.hasInvalidValue(planRegistratie.Status_Planologisch)
|| PlanValidationHelper.hasInvalidValue(planRegistratie.Knelpunten_Meerkeuze)
|| PlanValidationHelper.hasInvalidValue(planRegistratie.Regionale_Planlijst)
|| PlanValidationHelper.hasInvalidValue(planRegistratie.Toelichting_Knelpunten)
|| PlanValidationHelper.hasInvalidValue(planRegistratie.Flexwoningen)
|| PlanValidationHelper.hasInvalidValue(planRegistratie.Levensloopbestendig_Ja)
|| PlanValidationHelper.hasInvalidValue(planRegistratie.Levensloopbestendig_Nee)
|| PlanValidationHelper.hasInvalidValue(planRegistratie.Beoogd_Woonmilieu_ABF5)
|| PlanValidationHelper.hasInvalidValue(planRegistratie.Beoogd_Woonmilieu_ABF13)
|| PlanValidationHelper.hasInvalidValue(planRegistratie.Aantal_Studentenwoningen)
) {
return false;
}
return true;
}

private static hasInvalidValue(value: number | string | null | undefined) {
return typeof value === "undefined" || value === null;
}

}
73 changes: 71 additions & 2 deletions projects/planmonitor-wonen/src/lib/helpers/plancategorie.helper.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { BetaalbaarheidEnum, WonenEnZorgEnum, PlancategorieModel, WoningtypeEnum, DetailplanningModel } from '../models';
import { BetaalbaarheidEnum, DetailplanningModel, PlancategorieModel, WonenEnZorgEnum, WoningtypeEnum } from '../models';
import { NieuwbouwEnum } from '../models/nieuwbouw.enum';
import { FlexwoningenEnum } from '../models/flexwoningen.enum';
import { SloopEnum } from '../models/sloop.enum';
import { CategorieTableRowModel } from '../models/categorie-table-row.model';

export interface CategorieRowModel {
id: string;
Expand Down Expand Up @@ -38,7 +39,7 @@ export class PlancategorieHelper {
{ id: 'sloop-sloop', label: 'Sloop', groepnaam: 'sloop', field: 'Sloop', fieldValue: SloopEnum.SLOOP },
];

public static getNewPlancategorie(): Omit<PlancategorieModel, 'ID' | 'Planregistratie_ID'> {
public static getNewPlancategorie(initialData: Partial<PlancategorieModel> & Pick<PlancategorieModel, 'ID' | 'Planregistratie_ID'>): PlancategorieModel {
return {
Woningtype: null,
Nieuwbouw: null,
Expand All @@ -52,9 +53,64 @@ export class PlancategorieHelper {
Created: null,
Editor: null,
Edited: null,
...initialData,
};
}

public static getPlancategorieTable(
planCategorieen: PlancategorieModel[],
detailPlanningen: DetailplanningModel[],
): CategorieTableRowModel[] {
const nieuwbouwCategorie = PlancategorieHelper.getNieuwbouwCategorie(planCategorieen);
const nieuwbouwTotal = nieuwbouwCategorie?.Totaal_Gepland || 0;
const groupTotals = new Map<string, number>();
const rows = PlancategorieHelper.categorieen.map(categorieRow => {
const planCategorie = PlancategorieHelper.getPlanCategorie(categorieRow, planCategorieen);
const totalen = planCategorie?.Totaal_Gepland || 0;
const gerealiseerd = planCategorie?.Totaal_Gerealiseerd || 0;
const restcapaciteit = totalen - gerealiseerd;
const row: CategorieTableRowModel = {
id: categorieRow.id,
cls: 'group-' + categorieRow.field.toLowerCase(),
groep: categorieRow.field,
value: categorieRow.fieldValue,
label: categorieRow.label,
groeplabel: categorieRow.groepnaam,
totalen,
total_check: 0,
gerealiseerd,
restcapaciteit,
year_2024: PlancategorieHelper.getDetailplanningGeplandForYear(planCategorie, 2024, detailPlanningen) ?? '',
year_2025: PlancategorieHelper.getDetailplanningGeplandForYear(planCategorie, 2025, detailPlanningen) ?? '',
year_2026: PlancategorieHelper.getDetailplanningGeplandForYear(planCategorie, 2026, detailPlanningen) ?? '',
year_2027: PlancategorieHelper.getDetailplanningGeplandForYear(planCategorie, 2027, detailPlanningen) ?? '',
year_2028: PlancategorieHelper.getDetailplanningGeplandForYear(planCategorie, 2028, detailPlanningen) ?? '',
year_2029: PlancategorieHelper.getDetailplanningGeplandForYear(planCategorie, 2029, detailPlanningen) ?? '',
year_2030: PlancategorieHelper.getDetailplanningGeplandForYear(planCategorie, 2030, detailPlanningen) ?? '',
year_2031: PlancategorieHelper.getDetailplanningGeplandForYear(planCategorie, 2031, detailPlanningen) ?? '',
year_2032: PlancategorieHelper.getDetailplanningGeplandForYear(planCategorie, 2032, detailPlanningen) ?? '',
year_2033: PlancategorieHelper.getDetailplanningGeplandForYear(planCategorie, 2033, detailPlanningen) ?? '',
years_check: 0,
valid: false,
};
if (row.groep === 'Sloop') {
return row;
}
const rowTotaal = PlancategorieHelper.getTotalForRow(row);
row.years_check = restcapaciteit - rowTotaal;
groupTotals.set(categorieRow.field, (groupTotals.get(categorieRow.field) || 0) + totalen);
return row;
});
return rows.map(row => {
const totalCheck = nieuwbouwTotal - (groupTotals.get(row.groep) || 0);
return {
...row,
total_check: row.groep === 'Sloop' ? 0 : totalCheck,
valid: row.groep === 'Sloop' ? true : row.years_check === 0 && totalCheck === 0,
};
});
}

public static getNieuwbouwCategorie(planCategorien: PlancategorieModel[]) {
return PlancategorieHelper.getPlanCategorie(
{ field: "Nieuwbouw", fieldValue: NieuwbouwEnum.NIEUWBOUW },
Expand Down Expand Up @@ -89,4 +145,17 @@ export class PlancategorieHelper {
return detail ? detail.Aantal_Gepland : undefined;
}

private static getTotalForRow(row: CategorieTableRowModel) {
return (typeof row.year_2024 === 'number' ? row.year_2024 : 0) +
(typeof row.year_2025 === 'number' ? row.year_2025 : 0) +
(typeof row.year_2026 === 'number' ? row.year_2026 : 0) +
(typeof row.year_2027 === 'number' ? row.year_2027 : 0) +
(typeof row.year_2028 === 'number' ? row.year_2028 : 0) +
(typeof row.year_2029 === 'number' ? row.year_2029 : 0) +
(typeof row.year_2030 === 'number' ? row.year_2030 : 0) +
(typeof row.year_2031 === 'number' ? row.year_2031 : 0) +
(typeof row.year_2032 === 'number' ? row.year_2032 : 0) +
(typeof row.year_2033 === 'number' ? row.year_2033 : 0);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { PlancategorieModel } from './index';

export interface CategorieTableRowModel {
id: string;
cls: string;
groep: keyof PlancategorieModel;
value: string;
label: string;
groeplabel: string;
totalen: number;
total_check: number;
gerealiseerd: number;
restcapaciteit: number;
year_2024: number | string;
year_2025: number | string;
year_2026: number | string;
year_2027: number | string;
year_2028: number | string;
year_2029: number | string;
year_2030: number | string;
year_2031: number | string;
year_2032: number | string;
year_2033: number | string;
years_check: number;
valid: boolean;
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@
@for (year of yearRange; track $index) {
<ng-container [matColumnDef]="'year_' + year">
<mat-header-cell *matHeaderCellDef class="number-column">{{year}}</mat-header-cell>
<mat-cell *matCellDef="let row" class="year number-input-cell">
<input type="number" class="number-input" [value]="row['year_' + year]" (change)="updateDetailField($event, row.id, year)" />
<mat-cell *matCellDef="let row; let i = index;" class="year number-input-cell">
<input type="number" class="number-input" [class]="'year_' + year + '_' + i" [value]="row['year_' + year]" (change)="updateDetailField($event, row.id, year)" />
</mat-cell>
</ng-container>
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,33 +1,10 @@
import { Component, OnInit, ChangeDetectionStrategy, TrackByFunction, DestroyRef, ChangeDetectorRef } from '@angular/core';
import { PlancategorieHelper } from '../helpers/plancategorie.helper';
import { Component, ChangeDetectionStrategy, TrackByFunction, DestroyRef, ChangeDetectorRef, OnInit } from '@angular/core';
import { PlanregistratiesService } from '../services/planregistraties.service';
import { combineLatest, debounceTime } from 'rxjs';
import { PlancategorieModel } from '../models';
import { CategorieTableRowModel } from '../models/categorie-table-row.model';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { DetailplanningModel, PlancategorieModel, PlanregistratieModel } from '../models';

interface CategorieTableRow {
id: string;
cls: string;
groep: keyof PlancategorieModel;
value: string;
label: string;
groeplabel: string;
totalen: number;
total_check: number;
gerealiseerd: number;
restcapaciteit: number;
year_2024: number | string;
year_2025: number | string;
year_2026: number | string;
year_2027: number | string;
year_2028: number | string;
year_2029: number | string;
year_2030: number | string;
year_2031: number | string;
year_2032: number | string;
year_2033: number | string;
years_check: number;
}
const INTEGER_REGEX = /^\d+$/;

@Component({
selector: 'lib-plancategorie-list',
Expand Down Expand Up @@ -58,117 +35,48 @@ export class PlancategorieListComponent implements OnInit {
'years_check',
];

public tableData: CategorieTableRow[] | null = null;
public trackByRowId: TrackByFunction<CategorieTableRow> = (idx, row) => row.id;
public tableData: CategorieTableRowModel[] | null = null;
public trackByRowId: TrackByFunction<CategorieTableRowModel> = (idx, row) => row.id;

constructor(
private planregistratieService: PlanregistratiesService,
private destroyRef: DestroyRef,
private cdr: ChangeDetectorRef,
) { }

public ngOnInit(): void {
combineLatest([
this.planregistratieService.getSelectedPlanregistratie$(),
this.planregistratieService.getSelectedPlanCategorieen$(),
this.planregistratieService.getSelectedDetailplanningen$(),
])
.pipe(
takeUntilDestroyed(this.destroyRef),
debounceTime(10),
)
.subscribe(([ planregistratie, planCategorieen, detailPlanningen ]) => {
// console.log([ planregistratie, planCategorieen, detailPlanningen ]);
if (planregistratie === null || planCategorieen === null || detailPlanningen === null) {
this.tableData = null;
return;
}
this.prepareData(planregistratie, planCategorieen, detailPlanningen);
});
) {
}

private prepareData(planregistratie: PlanregistratieModel, planCategorieen: PlancategorieModel[], detailPlanningen: DetailplanningModel[]) {
const nieuwbouwCategorie = PlancategorieHelper.getNieuwbouwCategorie(planCategorieen);
const nieuwbouwTotal = nieuwbouwCategorie?.Totaal_Gepland || 0;
const groupTotals = new Map<string, number>();
const rows = PlancategorieHelper.categorieen.map(categorieRow => {
const planCategorie = PlancategorieHelper.getPlanCategorie(categorieRow, planCategorieen);
const totalen = planCategorie?.Totaal_Gepland || 0;
const gerealiseerd = planCategorie?.Totaal_Gerealiseerd || 0;
const restcapaciteit = totalen - gerealiseerd;
const row: CategorieTableRow = {
id: categorieRow.id,
cls: 'group-' + categorieRow.field.toLowerCase(),
groep: categorieRow.field,
value: categorieRow.fieldValue,
label: categorieRow.label,
groeplabel: categorieRow.groepnaam,
totalen,
total_check: 0,
gerealiseerd,
restcapaciteit,
year_2024: PlancategorieHelper.getDetailplanningGeplandForYear(planCategorie, 2024, detailPlanningen) ?? '',
year_2025: PlancategorieHelper.getDetailplanningGeplandForYear(planCategorie, 2025, detailPlanningen) ?? '',
year_2026: PlancategorieHelper.getDetailplanningGeplandForYear(planCategorie, 2026, detailPlanningen) ?? '',
year_2027: PlancategorieHelper.getDetailplanningGeplandForYear(planCategorie, 2027, detailPlanningen) ?? '',
year_2028: PlancategorieHelper.getDetailplanningGeplandForYear(planCategorie, 2028, detailPlanningen) ?? '',
year_2029: PlancategorieHelper.getDetailplanningGeplandForYear(planCategorie, 2029, detailPlanningen) ?? '',
year_2030: PlancategorieHelper.getDetailplanningGeplandForYear(planCategorie, 2030, detailPlanningen) ?? '',
year_2031: PlancategorieHelper.getDetailplanningGeplandForYear(planCategorie, 2031, detailPlanningen) ?? '',
year_2032: PlancategorieHelper.getDetailplanningGeplandForYear(planCategorie, 2032, detailPlanningen) ?? '',
year_2033: PlancategorieHelper.getDetailplanningGeplandForYear(planCategorie, 2033, detailPlanningen) ?? '',
years_check: 0,
};
const rowTotaal = PlancategorieListComponent.getTotalForRow(row);
row.years_check = restcapaciteit - rowTotaal;
groupTotals.set(categorieRow.field, (groupTotals.get(categorieRow.field) || 0) + totalen);
return row;
});
this.tableData = rows.map(row => {
return {
...row,
total_check: nieuwbouwTotal - (groupTotals.get(row.groep) || 0),
};
});
// console.log(this.tableData);
this.cdr.detectChanges();
public ngOnInit() {
this.planregistratieService.getSelectedCategorieTable$()
.pipe(takeUntilDestroyed(this.destroyRef))
.subscribe(tableData => {
this.tableData = tableData;
this.cdr.detectChanges();
});
}

public updateDetailField($event: Event, id: string, year: number) {
const target = $event.target;
if (!(target instanceof HTMLInputElement)) {
return;
}
const row = this.tableData?.find(p => p.id === id);
if (!row) {
const { row, value } = this.getRowAndInputValue($event, id);
if (row === null) {
return;
}
this.planregistratieService.updateDetailplanning(row.groep, row.value, year, +target.value);
this.planregistratieService.updateDetailplanning(row.groep, row.value, year, value);
}

public updateCategorieField($event: Event, id: string, field: keyof PlancategorieModel) {
const target = $event.target;
if (!(target instanceof HTMLInputElement)) {
return;
}
const row = this.tableData?.find(p => p.id === id);
if (!row) {
const { row, value } = this.getRowAndInputValue($event, id);
if (row === null) {
return;
}
this.planregistratieService.updateCategorieField(row.groep, row.value, field, +target.value);
this.planregistratieService.updateCategorieField(row.groep, row.value, field, value);
}

private static getTotalForRow(row: CategorieTableRow) {
return (typeof row.year_2024 === 'number' ? row.year_2024 : 0) +
(typeof row.year_2025 === 'number' ? row.year_2025 : 0) +
(typeof row.year_2026 === 'number' ? row.year_2026 : 0) +
(typeof row.year_2027 === 'number' ? row.year_2027 : 0) +
(typeof row.year_2028 === 'number' ? row.year_2028 : 0) +
(typeof row.year_2029 === 'number' ? row.year_2029 : 0) +
(typeof row.year_2030 === 'number' ? row.year_2030 : 0) +
(typeof row.year_2031 === 'number' ? row.year_2031 : 0) +
(typeof row.year_2032 === 'number' ? row.year_2032 : 0) +
(typeof row.year_2033 === 'number' ? row.year_2033 : 0);
private getRowAndInputValue($event: Event, id: string) {
const target = $event.target;
const row = this.tableData?.find(p => p.id === id);
if (!(target instanceof HTMLInputElement) || !INTEGER_REGEX.test(target.value) || !row) {
return { row: null, value: 0 };
}
return { row, value: +target.value };
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,17 @@
</mat-panel-title>
</mat-expansion-panel-header>
<lib-planregistratie-form [planregistratie]="selectedPlan"
(planregistratieChanged)="planregistratieChanged($event)"
(planregistratieValidChanged)="planregistratieValidChanged($event)"></lib-planregistratie-form>
(planregistratieChanged)="planregistratieChanged($event)"></lib-planregistratie-form>
</mat-expansion-panel>
</div>
<div class="details-form">
<lib-plancategorie-list></lib-plancategorie-list>
</div>
</div>
<div class="buttons">
<button (click)="cancel()" mat-flat-button>Annuleren</button>
<button (click)="save()"
[disabled]="!formValid || !formChanged"
[disabled]="disableSave$ | async"
color="primary"
mat-flat-button>Opslaan</button>
</div>
Expand Down
Loading

0 comments on commit ba85f67

Please sign in to comment.