Notifications + Plausibilitätsprüfung

This commit is contained in:
Moritz Utcke
2023-05-12 23:40:31 +04:00
parent 33c8a1d447
commit 5559f5ca4d
37 changed files with 855 additions and 357 deletions

View File

@@ -11,44 +11,57 @@
import moment from "moment";
import BilderZusatzsysteme from "../Ausweis/BilderZusatzsysteme.svelte";
import { Gebaeude } from "src/lib/Gebaeude";
import { hideLinkedElement, notifications } from "../Notifications/shared";
import { gebaeude } from "./shared";
import RawNotificationWrapper from "../Notifications/RawNotificationWrapper.svelte";
import RawNotification from "../Notifications/RawNotification.svelte";
import { auditHeizungGebaeudeBaujahr } from "./audits/HeizungGebaeudeBaujahr";
import { AuditType, hidden } from "./audits/hidden";
import { auditBedarfsausweisBenoetigt } from "./audits/BedarfsausweisBenoetigt";
import { auditVerbrauchAbweichung } from "./audits/VerbrauchAbweichung";
export let gebaeude: Gebaeude;
export let uid: string = "";
$: ausweis = gebaeude.ausweis || new Verbrauchsausweis();
gebaeude.set(new Gebaeude());
$gebaeude.ausweis = new Verbrauchsausweis();
$gebaeude.ausweis.gebaeude = $gebaeude;
if (uid) {
(async () => {
const result = await fetch(`/api/verbrauchsausweis?uid=${uid}`, {
method: "GET"
});
let needsRequirementCertificate: boolean = false;
const json = await result.json();
$: needsRequirementCertificate =
(gebaeude.baujahr < 1978 &&
gebaeude.einheiten <= 4 &&
gebaeude.saniert == false &&
(ausweis.ausstellgrund == "Vermietung" ||
ausweis.ausstellgrund == "Sonstiges")) ||
ausweis.ausstellgrund == "Neubau" ||
ausweis.ausstellgrund == "Modernisierung" ||
ausweis.ausstellgrund == "Verkauf";
if (json.success) {
gebaeude.set(new Gebaeude(json.data.gebaeude));
$gebaeude.ausweis = new Verbrauchsausweis(json.data.ausweis);
$gebaeude.ausweis.gebaeude = $gebaeude;
}
})
}
$: ausweis = $gebaeude.ausweis || new Verbrauchsausweis();
function automatischAusfüllen() {
gebaeude.baujahr = 1962;
ausweis.baujahr_anlage = 1974;
gebaeude.saniert = true;
gebaeude.einheiten = 1;
$gebaeude.baujahr = 1962;
ausweis.baujahr_anlage = 1952;
$gebaeude.saniert = true;
$gebaeude.einheiten = 1;
ausweis.ausstellgrund = "Vermietung";
ausweis.kennwerte.verbrauch_1 = 15000;
ausweis.kennwerte.verbrauch_2 = 14000;
ausweis.kennwerte.verbrauch_3 = 16000;
gebaeude.wohnflaeche = 152;
gebaeude.keller_beheizt = true;
$gebaeude.wohnflaeche = 152;
$gebaeude.keller_beheizt = true;
ausweis.kennwerte.energietraeger_1 = "Erdgas H";
ausweis.kennwerte.einheit_1 = "kWh";
ausweis.kennwerte.anteil_warmwasser_1 = 18;
ausweis.kennwerte.zeitraum = moment("12.01.2019");
gebaeude.plz = "21039";
gebaeude.ort = "Hamburg";
gebaeude.strasse = "Curslacker Deich 170";
gebaeude.gebaeudeteil = "Gesamtgebäude";
//ausweis.upload();
$gebaeude.plz = "21039";
$gebaeude.ort = "Hamburg";
$gebaeude.strasse = "Curslacker Deich 170";
$gebaeude.gebaeudeteil = "Gesamtgebäude";
}
</script>
@@ -81,29 +94,7 @@
<Label>A - Prüfung der Ausweisart</Label>
<Ausweisart bind:gebaeude />
<div
class="flex flex-col p-4"
class:hidden={!needsRequirementCertificate}
>
<div class="form-group col-md-9">
<HelpLabel
title="Sie benötigen einen Bedarfsausweis. Bitte führen Sie hier Ihre Eingabe für den Bedarfsausweis fort und klicken auf den Button:"
>
Der Bedarfsausweis ist die etwas umfangreichere Berechnung.
Sie benötigen z.B. Länge, Breite und Geschoßhöhe des
Gebäudes. Auch müssen genauere Angaben zur Anlagentechnik
gemacht werden.
</HelpLabel>
</div>
<div class="form-group col-md-3">
<a class="button" href="/bedarfsausweis"
>Bedarfsausweis erstellen</a
>
</div>
</div>
<Ausweisart bind:gebaeude={$gebaeude} />
<hr />
@@ -128,7 +119,7 @@
required
data-msg-minlength="min. 5 Zeichen"
data-msg-maxlength="max. 40 Zeichen"
bind:value={gebaeude.strasse}
bind:value={$gebaeude.strasse}
/>
</div>
</div>
@@ -136,8 +127,8 @@
<!-- PLZ -->
<div class="form-group col-md-4 PLZ">
<ZipSearch
bind:zip={gebaeude.plz}
bind:city={gebaeude.ort}
bind:zip={$gebaeude.plz}
bind:city={$gebaeude.ort}
name="zip"
/>
</div>
@@ -151,7 +142,7 @@
<input
name="IGort"
readonly={true}
bind:value={gebaeude.ort}
bind:value={$gebaeude.ort}
type="text"
/>
</div>
@@ -173,7 +164,7 @@
autocomplete="off"
data-rule-minlength="2"
data-msg-minlength="min. 2 Zeichen"
bind:value={gebaeude.wohnflaeche}
bind:value={$gebaeude.wohnflaeche}
/>
</div>
</div>
@@ -185,7 +176,7 @@
<select
name="IGkeller"
required
bind:value={gebaeude.keller_beheizt}
bind:value={$gebaeude.keller_beheizt}
>
<option>Bitte auswählen</option>
<option value={false}>nicht vorhanden</option>
@@ -214,7 +205,7 @@
<Label>C - Eingabe von 3 zusammenhängenden Verbrauchsjahren</Label>
<div class="GRB">
<Verbrauch bind:ausweis />
<Verbrauch bind:gebaeude={$gebaeude} />
</div>
<hr />
@@ -287,7 +278,7 @@
><input
type="checkbox"
name="IGversorgungssysteme1"
bind:checked={gebaeude.energiequelle_2_nutzung[0]}
bind:checked={$gebaeude.energiequelle_2_nutzung[0]}
value="Heizung"
/>Heizung</label
>
@@ -295,7 +286,7 @@
><input
type="checkbox"
name="IGversorgungssysteme2"
bind:checked={gebaeude.energiequelle_2_nutzung[1]}
bind:checked={$gebaeude.energiequelle_2_nutzung[1]}
value="Warmwasser"
/>Warmwasser</label
>
@@ -303,7 +294,7 @@
><input
type="checkbox"
name="IGversorgungssysteme3"
bind:checked={gebaeude.energiequelle_2_nutzung[2]}
bind:checked={$gebaeude.energiequelle_2_nutzung[2]}
value="Lüftung"
/>Lüftung</label
>
@@ -311,7 +302,7 @@
><input
type="checkbox"
name="IGversorgungssysteme4"
bind:checked={gebaeude.energiequelle_2_nutzung[3]}
bind:checked={$gebaeude.energiequelle_2_nutzung[3]}
value="Kühlung"
/>Kühlung</label
>
@@ -450,7 +441,7 @@
>F - Bitte prüfen Sie hier die Angaben zum Sanierungszustand des
Gebäudes</Label
>
<BilderZusatzsysteme {gebaeude} />
<BilderZusatzsysteme gebaeude={$gebaeude} />
<hr />
<div class="flex flex-row justify-between">
<Hilfe />
@@ -458,3 +449,63 @@
</div>
</fieldset>
</form>
<RawNotificationWrapper>
{#each Object.entries($notifications) as [uid, notification] (uid)}
<RawNotification notification={{...notification, uid }}>
{@html notification.subtext}
</RawNotification>
{/each}
{#if auditBedarfsausweisBenoetigt($gebaeude)}
<RawNotification notification={{
message: "Bedarfsausweis benötigt!",
timeout: 0,
uid: "BEDARFSAUSWEIS",
dismissable: false,
type: "info"
}}>
Sie benötigen einen Bedarfsausweis. <a href='/bedarfsausweis'>Bitte führen Sie hier Ihre Eingabe für den Bedarfsausweis fort</a>.
</RawNotification>
{/if}
{#if auditHeizungGebaeudeBaujahr($gebaeude)}
<RawNotification notification={{
message: "Plausibilitätsprüfung",
timeout: 0,
uid: "HEIZUNG_VOR_GEBAEUDE",
dismissable: true,
onUserDismiss: () => {
hidden.add(AuditType.HEIZUNG_GEBAEUDE_BAUJAHR)
$gebaeude = $gebaeude;
},
type: "warning"
}}>
Sie haben angegeben, dass ihre Heizung vor ihrem Gebäude konstruiert wurde. Sind sie sich sicher, dass das stimmt?
</RawNotification>
{/if}
{#if auditVerbrauchAbweichung($gebaeude).length > 0}
<RawNotification notification={{
message: "Plausibilitätsprüfung",
timeout: 0,
uid: "VERBRAUCH_ABWEICHUNG",
dismissable: true,
onUserDismiss: () => {
hidden.add(AuditType.VERBRAUCH_ABWEICHUNG)
$gebaeude = $gebaeude;
},
type: "warning"
}}>
Die Abweichung der Verbräuche zwischen Zeitraum {auditVerbrauchAbweichung($gebaeude)[0]} und {auditVerbrauchAbweichung($gebaeude)[1]} beträgt mehr als 25% und sie haben keinen Leerstand angegeben. Sind sie sich sicher, dass das stimmt?
</RawNotification>
{/if}
</RawNotificationWrapper>
<style>
:global(.linked) {
@apply border-2 border-red-400;
}
</style>

View File

@@ -0,0 +1,41 @@
export function lookupAudit(audit: keyof typeof audits): boolean {
if (!audits.hasOwnProperty(audit)) {
return false;
}
const valid = audits[audit].validator(hidden);
if (valid && !hidden.has(audit)) {
audits[audit].trueAction(hidden);
} else {
audits[audit].falseAction(hidden);
}
return valid;
}
type Action = (x: typeof hidden) => void;
export function addAudit(
name: string,
validator: (x: typeof hidden) => boolean,
trueAction: Action,
falseAction: Action
) {
audits[name] = {
validator,
trueAction,
falseAction,
};
}
export const audits: Record<
string,
{
validator: (x: typeof hidden) => boolean;
trueAction: Action;
falseAction: Action;
}
> = {};
export const hidden: Set<keyof typeof audits> = new Set();

View File

@@ -0,0 +1,17 @@
import { Gebaeude } from "src/lib/Gebaeude";
export function auditBedarfsausweisBenoetigt(gebaeude: Gebaeude): boolean {
let ausweis = gebaeude.ausweis;
if (!ausweis) {
return false;
}
return ((gebaeude.baujahr < 1978 &&
gebaeude.einheiten <= 4 &&
gebaeude.saniert == false &&
(ausweis.ausstellgrund == "Vermietung" ||
ausweis.ausstellgrund == "Sonstiges")) ||
ausweis.ausstellgrund == "Neubau" ||
ausweis.ausstellgrund == "Modernisierung" ||
ausweis.ausstellgrund == "Verkauf");
}

View File

@@ -0,0 +1,14 @@
import { Gebaeude } from "src/lib/Gebaeude";
import { AuditType, hidden } from "../audits/hidden";
export function auditHeizungGebaeudeBaujahr(gebaeude: Gebaeude): boolean {
let ausweis = gebaeude.ausweis;
if (!ausweis) {
return false;
}
return ausweis.baujahr_anlage > 1500 &&
gebaeude.baujahr > 1500 &&
ausweis.baujahr_anlage < gebaeude.baujahr
&& !hidden.has(AuditType.HEIZUNG_GEBAEUDE_BAUJAHR)
}

View File

@@ -0,0 +1,37 @@
import { Gebaeude } from "src/lib/Gebaeude";
import { AuditType, hidden } from "./hidden";
export function auditVerbrauchAbweichung(gebaeude: Gebaeude): number[] {
let ausweis = gebaeude.ausweis;
if (!ausweis || gebaeude.leerstand > 0) {
return [];
}
if (hidden.has(AuditType.VERBRAUCH_ABWEICHUNG)) {
return [];
}
if (getAbweichung(ausweis.kennwerte.verbrauch_1, ausweis.kennwerte.verbrauch_2) > 0.25) {
return [1, 2];
}
if (getAbweichung(ausweis.kennwerte.verbrauch_2, ausweis.kennwerte.verbrauch_3) > 0.25) {
return [2, 3];
}
if (getAbweichung(ausweis.kennwerte.verbrauch_4, ausweis.kennwerte.verbrauch_5) > 0.25) {
return [4, 5];
}
if (getAbweichung(ausweis.kennwerte.verbrauch_5, ausweis.kennwerte.verbrauch_6) > 0.25) {
return [5, 6];
}
return [];
}
function getAbweichung(x: number, y: number): number {
console.log(x, y, Math.abs((x - y) / ((x + y) / 2)));
return Math.abs((x - y) / ((x + y) / 2));
}

View File

@@ -0,0 +1,6 @@
export const hidden = new Set<AuditType>()
export enum AuditType {
HEIZUNG_GEBAEUDE_BAUJAHR,
VERBRAUCH_ABWEICHUNG
}

View File

@@ -0,0 +1,4 @@
import { Gebaeude } from "src/lib/Gebaeude";
import { Writable, writable } from "svelte/store";
export const gebaeude: Writable<Gebaeude> = writable();