Frau Aydin, die Disponentin bei Brandt Haustechnik, will, dass die Rechnung aus dem Auftragsbuch auch auf der Webseite der Firma
erscheint, später auch in einer App für die Monteure. Die Frage an Sie lautet: Wo steht, wie eine Rechnung berechnet wird? Die
Antwort aus der Inventur (Lektion M1.3) war unbequem: in der Klasse HauptForm, einem Fenster. Solange das so ist, kann kein
anderes Programm die Preise berechnen, ohne ein Fenster mitzuziehen.
Diese Lektion löst die Preisregeln aus dem Formular, in einer Bibliothek ohne Windows-Bezug und mit Tests. Sie ist die erste
Naht der Reihenfolge aus Lektion M1.4 (N1), und alles Weitere in diesem Kurs baut darauf auf: Die Web-API, die Blazor-Seiten und die
Datenbankzugriffe rufen später diese Bibliothek. Vorausgesetzt ist Modul 2: Das Auftragsbuch läuft als net10.0-windows, und
die Charakterisierungstests aus Lektion M2.1 sind Ihr Sicherheitsnetz. Zur Architektur dahinter siehe K4, Modul 4.3
(Ports and Adapters) und 4.10 (Code-Architektur); hier geht es nur um den ersten, kleinen Schnitt.
Fachlogik im Formular erkennen
„Fachlogik“ ist das, was ein Fachbereich als Regel formulieren würde: Mindestens eine Stunde wird berechnet, Wartungsaufträge kosten keine Anfahrt, ein Auftrag muss erledigt sein, bevor man ihn abrechnet. Regeln dieser Art sind im Auftragsbuch an vier Merkmalen zu erkennen:
| Merkmal | Beispiel im Auftragsbuch | Folge |
|---|---|---|
| Es rechnet oder entscheidet mit Werten | Arbeit, Anfahrt, Netto, Brutto; die Prüfung des Status vor dem Druck |
Gehört in die Bibliothek |
| Es kennt Technik der Oberfläche | DataRow, MessageBox, ConfigurationManager |
Bleibt im Formular oder wird als Parameter hereingereicht |
| Andere rufen es auf | Rechnungsdruck und Exporte rufen HauptForm.Netto(...) |
Das Formular ist zur Bibliothek geworden |
| Regel und Meldung stehen im selben Satz | Der Test auf „noch nicht erledigt“ und der Text der Meldung | Regel herauslösen, Text dem Formular lassen |
Das dritte Merkmal finden Sie mit einer Suche, die nur liest:
Select-String -Path .\Brandt.Auftragsbuch\*.cs -Pattern 'HauptForm\.(Arbeit|Anfahrt|MaterialMitAufschlag|Netto|Brutto)\(' |
ForEach-Object { '{0}: {1}' -f $_.Filename, $_.Line.Trim() }
Exporte.cs: decimal netto = HauptForm.Netto(auftrag);
Exporte.cs: decimal brutto = HauptForm.Brutto(auftrag);
Rechnungsdruck.cs: Position(g, normal, rechts, ref y, x, zeile, "Arbeit", HauptForm.Arbeit(_auftrag));
Rechnungsdruck.cs: Position(g, normal, rechts, ref y, x, zeile, "Anfahrt", HauptForm.Anfahrt(_auftrag));
Rechnungsdruck.cs: Position(g, normal, rechts, ref y, x, zeile, "Material", HauptForm.MaterialMitAufschlag(_auftrag));
Rechnungsdruck.cs: Position(g, normal, rechts, ref y, x, zeile, "Netto", HauptForm.Netto(_auftrag));
Rechnungsdruck.cs: Position(g, normal, rechts, ref y, x, zeile, "Brutto", HauptForm.Brutto(_auftrag));
Sieben Aufrufer in zwei Dateien, und beide Dateien haben mit dem Fenster nichts zu tun. Das ist der Beleg: Die Regeln sind längst
gemeinsamer Besitz des Programms, sie wohnen nur an der falschen Adresse. Und sie hängen an einer Zeile aus der Datenbank
(DataRow) und an Einstellungen, also an Technik, die eine Bibliothek nicht kennen soll.
Die Regeln selbst haben Sie aus Lektion M1.2 vor sich:
Arbeitist das Größere aus Stunden und einer Stunde, mal Stundensatz.Anfahrtist null bei Wartungsaufträgen, sonst die Anfahrtspauschale.MaterialMitAufschlagist das Material mal 1,15, auf zwei Stellen gerundet.Nettoist die Summe der drei;Bruttoist Netto mal (1 plus Mehrwertsteuersatz), auf zwei Stellen gerundet.