Ergänzung von Diagrammen Gruppe A
parent
3846ba0cde
commit
c89e9a5c6f
|
|
@ -3,7 +3,7 @@ title: "Pflichtenheft"
|
|||
subtitle: "Desktop-Fakturierungsanwendung — Gruppe A: Prozess / Dokumentenzyklus"
|
||||
author:
|
||||
- Team 1 – Gruppe A
|
||||
version: "1.0"
|
||||
version: "1.1"
|
||||
lang: de-DE
|
||||
toc: true
|
||||
toc-depth: 3
|
||||
|
|
@ -22,7 +22,7 @@ header-includes: |
|
|||
\fancyhf{}
|
||||
\fancyhead[L]{Team 1 – Gruppe A}
|
||||
\fancyhead[C]{Pflichtenheft}
|
||||
\fancyhead[R]{Version 1.0}
|
||||
\fancyhead[R]{Version 1.1}
|
||||
\fancyfoot[C]{\thepage\ /\ \pageref{LastPage}}
|
||||
\renewcommand{\headrulewidth}{0.4pt}
|
||||
\renewcommand{\footrulewidth}{0pt}
|
||||
|
|
@ -50,6 +50,7 @@ und den Modultest der Komponente *Prozess / Dokumentenzyklus*.
|
|||
| Version | Datum | Autor | Grund der Änderung |
|
||||
|---------|------------|-----------------------------|---------------------|
|
||||
| 1.0 | 09.06.2026 | Lucas Strubel, Luca Kaiser | Initiale Erstellung |
|
||||
| 1.1 | 13.06.2026 | Lucas Strubel, Luca Kaiser | Einfügen der UML-Diagramme (Klassen- und Sequenzdiagramm) |
|
||||
|
||||
\newpage
|
||||
|
||||
|
|
@ -391,32 +392,33 @@ public interface BelegnummernGenerator {
|
|||
## 7. Systemarchitektur (logisch, grob)
|
||||
|
||||
Die Komponente folgt einer einfachen Schichtung: die GUI (Gruppe D) ruft den
|
||||
`DokumentService` auf, der die Fachlogik kapselt und die Dienste `BelegnummernGenerator`,
|
||||
`KundenService`, `ProduktService` und `PdfExporter` nutzt. Belege werden über ein
|
||||
`DokumentRepository` im lokalen Dateisystem persistiert.
|
||||
`DokumentService` (realisiert durch `StandardDokumentService`) auf, der die Fachlogik
|
||||
kapselt und die Dienste `BelegnummernGenerator`, `KundenService`, `ProduktService` und
|
||||
`PdfExporter` nutzt. Belege werden über ein `DokumentRepository` im lokalen Dateisystem
|
||||
persistiert (realisiert als JSON-Ablage). Nach jeder schreibenden Operation meldet der
|
||||
`DokumentService` die Datenänderung über einen **`EreignisBus`** (Observer-Muster, Paket
|
||||
`gemeinsam`; `melde(DatenBereich.DOKUMENTE)`); die Modulansichten der Gruppe D abonnieren
|
||||
diesen Bus und aktualisieren sich automatisch.
|
||||
|
||||
### 7.1 Klassendiagramm
|
||||
|
||||
<!-- TODO: UML-Klassendiagramm hier einfügen (Abbildung 1) -->
|
||||
|
||||
![Abbildung 1: UML-Klassendiagramm Dokumentenzyklus (Gruppe A)]
|
||||

|
||||
|
||||
**Beschreibung zu Abbildung 1:** Das Klassendiagramm zeigt die abstrakte Oberklasse
|
||||
`Dokument` mit den Spezialisierungen `Angebot`, `Auftragsbestaetigung`, `Lieferschein` und
|
||||
`Rechnung` (Vererbung). Ein `Dokument` besteht aus einer bis vielen `Dokumentposition`-
|
||||
Objekten (Komposition `Dokument` ◆—— `Dokumentposition`, Multiplizität `1..*`). Jede
|
||||
Objekten (Komposition zwischen `Dokument` und `Dokumentposition`, Multiplizität `1..*`). Jede
|
||||
`Dokumentposition` referenziert ein `Produkt` (Gruppe B), ein `Dokument` referenziert einen
|
||||
`Kunde` (Gruppe C) — jeweils über die Stammdatennummer (lose Kopplung). Der `DokumentService`
|
||||
orchestriert die Erstellung und nutzt den `BelegnummernGenerator` (Vergabe lückenloser
|
||||
Belegnummern), die Schnittstellen `KundenService`/`ProduktService` (Stammdaten) sowie den
|
||||
`PdfExporter` (PDF-Export). Der Status eines Belegs wird über das Enum `DokumentStatus`
|
||||
abgebildet.
|
||||
Belegnummern), die Schnittstellen `KundenService`/`ProduktService` (Stammdaten), den
|
||||
`PdfExporter` (PDF-Export) sowie den `EreignisBus` (Benachrichtigung der Modulansichten
|
||||
nach Datenänderungen, Observer-Muster). Der Status eines Belegs wird über das Enum
|
||||
`DokumentStatus` abgebildet.
|
||||
|
||||
### 7.2 Sequenzdiagramm
|
||||
|
||||
<!-- TODO: UML-Sequenzdiagramm hier einfügen (Abbildung 2) -->
|
||||
|
||||
![Abbildung 2: UML-Sequenzdiagramm „Rechnung erstellen" (Gruppe A)]
|
||||

|
||||
|
||||
**Beschreibung zu Abbildung 2:** Das Sequenzdiagramm stellt den Ablauf *Rechnung erstellen*
|
||||
dar. Die Anwender:in löst über die GUI (Gruppe D) `erstelleRechnung(kundenNr, positionen)`
|
||||
|
|
@ -425,8 +427,11 @@ am `DokumentService` aus. Dieser ermittelt über `KundenService.findeKunde(...)`
|
|||
Summe Netto-, Steuer- und Bruttobetrag (F-23), fordert vom `BelegnummernGenerator` mit
|
||||
`naechsteNummer(RECHNUNG, jahr)` eine lückenlose Rechnungsnummer an (GR-01), setzt das
|
||||
Standard-Zahlungsziel (+14 Tage, GR-06), persistiert den Beleg über das `DokumentRepository`
|
||||
und exportiert ihn über `PdfExporter.exportiere(...)`. Abschließend wird die gespeicherte
|
||||
`Rechnung` an die GUI zurückgegeben.
|
||||
und meldet die Änderung über `EreignisBus.melde(DOKUMENTE)` an die abonnierten Modulansichten.
|
||||
Abschließend wird die gespeicherte `Rechnung` an die GUI zurückgegeben. Der PDF-Export ist ein
|
||||
**separater** Vorgang (im Diagramm unten dargestellt): über `exportierePdf(...)` lädt der
|
||||
`DokumentService` den Beleg erneut aus dem `DokumentRepository` und exportiert ihn mittels
|
||||
`PdfExporter.exportiere(...)` in das lokale Dateisystem (F-15, IF-01).
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -516,21 +521,57 @@ Die folgenden Testfälle sind deterministisch (feste Ein-/Ausgaben) und mit JUni
|
|||
umsetzbar. Geldbeträge werden als `BigDecimal` mit Scale 2 erwartet
|
||||
(`assertEquals(new BigDecimal("119.00"), …)` bzw. `compareTo`).
|
||||
|
||||
+-------+--------------------+-----------------------------+---------------------------+-----------------------------+
|
||||
| TC | Abgedeckte PH-Anf. | Vorbedingung | Eingabe | Erwartetes Ergebnis |
|
||||
|-------|--------------------|--------------|---------|---------------------|
|
||||
| TC-01 | F-23, F-03 | Position mit Netto 100.00 €, Steuersatz 0.19 | `berechne()` | Steuer = 19.00, Brutto = 119.00 (Scale 2) |
|
||||
| TC-02 | F-23 | Einzelpreis 50.00 €, Menge 3 | Positionssumme berechnen | positionssummeNetto = 150.00 |
|
||||
| TC-03 | F-03, F-13 | Beleg mit 2 Positionen (150.00 € @ 0.19; 50.00 € @ 0.07) | Summen berechnen | summeNetto = 200.00, summeSteuer = 32.00, summeBrutto = 232.00 |
|
||||
| TC-04 | F-12, GR-01 | Letzte Rechnungsnummer `R-2026-000123` | `naechsteNummer(RECHNUNG, 2026)` | liefert `R-2026-000124` (lückenlos) |
|
||||
| TC-05 | F-12 (Format) | Zähler = 7, Jahr 2026 | `naechsteNummer(RECHNUNG, 2026)` | liefert `R-2026-000007` (führende Nullen, `String`) |
|
||||
| TC-06 | F-14, GR-06 | Rechnungsdatum 2026-06-09, kein Zahlungsziel | Rechnung erstellen | zahlungsziel = 2026-06-23 (+14 Tage) |
|
||||
| TC-07 | F-14 | Rechnungsdatum 2026-06-09, Zahlungsziel 2026-07-31 | Rechnung erstellen | zahlungsziel = 2026-07-31 (übernommen) |
|
||||
| TC-08 | F-24, NF-INT-01 | Rechnung im Status `VERSENDET` | `setzePosition(...)` / Änderung | wirft `IllegalStateException` |
|
||||
| TC-09 | F-19, F-20 | Rechnung im Status `OFFEN` | `storniere()` | Status = `STORNIERT`; nicht in `offeneRechnungen()`; `storniertAm` gesetzt |
|
||||
| TC-10 | F-22, GR-05 | Angebot `AN-2026-000001` mit Kunde + 2 Positionen | `ausAngebot(angebot)` (AB erzeugen) | AB übernimmt Kunde/Positionen/Mengen; `vorgaengerNr = "AN-2026-000001"` |
|
||||
| TC-11 | F-23, F-24 | Rechnung mit Produkt @ 50.00 €; danach Produktpreis → 80.00 € | erste Rechnung erneut lesen | einzelpreisNetto bleibt 50.00 (Snapshot unverändert) |
|
||||
| TC-12 | F-18, NF-USE-02 | Rechnung ohne Kunde **oder** ohne Position | `speichere()` | Speichern abgelehnt; Validierungsfehler benennt fehlendes Pflichtfeld |
|
||||
| TC-13 | F-11, F-12, F-13 | Kunde + 1 Position vorhanden | vollständige Rechnung erstellen | Rechnung gespeichert, Nummer vergeben, alle § 14 UStG-Pflichtangaben gesetzt |
|
||||
+=======+====================+=============================+===========================+=============================+
|
||||
| TC-01 | F-23, F-03 | Position mit Netto 100.00 | `berechne()` | Steuer = 19.00, Brutto = |
|
||||
| | | €, Steuersatz 0.19 | | 119.00 (Scale 2) |
|
||||
+-------+--------------------+-----------------------------+---------------------------+-----------------------------+
|
||||
| TC-02 | F-23 | Einzelpreis 50.00 €, | Positionssumme | positionssummeNetto = |
|
||||
| | | Menge 3 | berechnen | 150.00 |
|
||||
+-------+--------------------+-----------------------------+---------------------------+-----------------------------+
|
||||
| TC-03 | F-03, F-13 | Beleg mit 2 Positionen | Summen berechnen | summeNetto = 200.00, |
|
||||
| | | (150.00 € @ 0.19; | | summeSteuer = 32.00, |
|
||||
| | | 50.00 € @ 0.07) | | summeBrutto = 232.00 |
|
||||
+-------+--------------------+-----------------------------+---------------------------+-----------------------------+
|
||||
| TC-04 | F-12, GR-01 | Letzte Rechnungsnummer | `naechsteNummer` | liefert `R-2026-000124` |
|
||||
| | | `R-2026-000123` | `(RECHNUNG, 2026)` | (lückenlos) |
|
||||
+-------+--------------------+-----------------------------+---------------------------+-----------------------------+
|
||||
| TC-05 | F-12 (Format) | Zähler = 7, Jahr 2026 | `naechsteNummer` | liefert `R-2026-000007` |
|
||||
| | | | `(RECHNUNG, 2026)` | (führende Nullen, `String`) |
|
||||
+-------+--------------------+-----------------------------+---------------------------+-----------------------------+
|
||||
| TC-06 | F-14, GR-06 | Rechnungsdatum 2026-06-09, | Rechnung erstellen | zahlungsziel = |
|
||||
| | | kein Zahlungsziel | | 2026-06-23 (+14 Tage) |
|
||||
+-------+--------------------+-----------------------------+---------------------------+-----------------------------+
|
||||
| TC-07 | F-14 | Rechnungsdatum 2026-06-09, | Rechnung erstellen | zahlungsziel = 2026-07-31 |
|
||||
| | | Zahlungsziel 2026-07-31 | | (übernommen) |
|
||||
+-------+--------------------+-----------------------------+---------------------------+-----------------------------+
|
||||
| TC-08 | F-24, NF-INT-01 | Rechnung im Status | `setzePosition(...)` / | wirft |
|
||||
| | | `VERSENDET` | Änderung | `IllegalStateException` |
|
||||
+-------+--------------------+-----------------------------+---------------------------+-----------------------------+
|
||||
| TC-09 | F-19, F-20 | Rechnung im Status `OFFEN` | `storniere()` | Status = `STORNIERT`; |
|
||||
| | | | | nicht in |
|
||||
| | | | | `offeneRechnungen()`; |
|
||||
| | | | | `storniertAm` gesetzt |
|
||||
+-------+--------------------+-----------------------------+---------------------------+-----------------------------+
|
||||
| TC-10 | F-22, GR-05 | Angebot `AN-2026-000001` | `ausAngebot(angebot)` | AB übernimmt Kunde/ |
|
||||
| | | mit Kunde + 2 Positionen | (AB erzeugen) | Positionen/Mengen; |
|
||||
| | | | | `vorgaengerNr` = |
|
||||
| | | | | `"AN-2026-000001"` |
|
||||
+-------+--------------------+-----------------------------+---------------------------+-----------------------------+
|
||||
| TC-11 | F-23, F-24 | Rechnung mit Produkt @ | erste Rechnung erneut | einzelpreisNetto bleibt |
|
||||
| | | 50.00 €; danach | lesen | 50.00 (Snapshot |
|
||||
| | | Produktpreis → 80.00 € | | unverändert) |
|
||||
+-------+--------------------+-----------------------------+---------------------------+-----------------------------+
|
||||
| TC-12 | F-18, NF-USE-02 | Rechnung ohne Kunde | `speichere()` | Speichern abgelehnt; |
|
||||
| | | **oder** ohne Position | | Validierungsfehler benennt |
|
||||
| | | | | fehlendes Pflichtfeld |
|
||||
+-------+--------------------+-----------------------------+---------------------------+-----------------------------+
|
||||
| TC-13 | F-11, F-12, F-13 | Kunde + 1 Position | vollständige Rechnung | Rechnung gespeichert, |
|
||||
| | | vorhanden | erstellen | Nummer vergeben, alle |
|
||||
| | | | | § 14 UStG-Pflichtangaben |
|
||||
| | | | | gesetzt |
|
||||
+-------+--------------------+-----------------------------+---------------------------+-----------------------------+
|
||||
|
||||
Damit sind 13 Testfälle (> 10) spezifiziert, die alle funktionalen Kernregeln (F-12, F-14,
|
||||
F-18, F-22, F-23, F-24) sowie die zentralen Geschäftsregeln (GR-01, GR-02, GR-03, GR-05,
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -347,7 +347,11 @@ Die Komponente folgt einer einfachen Schichtung: die GUI (Gruppe D) ruft den
|
|||
Löschsperre) kapselt und die Dienste `ProduktnummernGenerator`, `ProduktRepository` und
|
||||
`ProduktReferenzPruefung` (Gruppe A) nutzt. Gegenüber Gruppe A implementiert die
|
||||
Komponente das Interface `ProduktService`. Produkte werden über das `ProduktRepository`
|
||||
im lokalen Dateisystem persistiert.
|
||||
im lokalen Dateisystem persistiert (realisiert als JSON-Ablage). Nach jeder schreibenden
|
||||
Operation (Anlegen, Ändern, Löschen) meldet der `ProduktVerwaltungsService` die Änderung
|
||||
über einen **`EreignisBus`** (Observer-Muster, Paket `gemeinsam`;
|
||||
`melde(DatenBereich.PRODUKTE)`), den die Produktansicht der Gruppe D abonniert und sich
|
||||
daraufhin automatisch aktualisiert.
|
||||
|
||||
### 7.1 Klassendiagramm
|
||||
|
||||
|
|
@ -361,8 +365,10 @@ mit ihren Attributen (Kapitel 6.1). Der `ProduktVerwaltungsService` orchestriert
|
|||
Produktnummern, F-02), das `ProduktRepository` (Persistenz, IF-01) und die von Gruppe A
|
||||
bereitgestellte Schnittstelle `ProduktReferenzPruefung` (Löschsperre, F-09/F-10).
|
||||
Zusätzlich realisiert der `ProduktVerwaltungsService` das Interface `ProduktService`
|
||||
(lesender Zugriff für Gruppe A, F-14). Dokumentpositionen (Gruppe A) referenzieren ein
|
||||
`Produkt` ausschließlich über die Produktnummer (lose Kopplung).
|
||||
(lesender Zugriff für Gruppe A, F-14) und meldet Datenänderungen über den `EreignisBus`
|
||||
(Observer-Muster) an die abonnierte Produktansicht der Gruppe D. Dokumentpositionen
|
||||
(Gruppe A) referenzieren ein `Produkt` ausschließlich über die Produktnummer (lose
|
||||
Kopplung).
|
||||
|
||||
### 7.2 Sequenzdiagramm
|
||||
|
||||
|
|
|
|||
|
|
@ -349,7 +349,11 @@ Die Komponente folgt einer einfachen Schichtung: die GUI (Gruppe D) ruft den
|
|||
Löschsperre GR-04) kapselt und die Dienste `KundennummernGenerator`, `KundenRepository`
|
||||
und `KundenReferenzPruefung` (Gruppe A) nutzt. Gegenüber Gruppe A implementiert die
|
||||
Komponente das Interface `KundenService`. Kunden werden über das `KundenRepository` im
|
||||
lokalen Dateisystem persistiert.
|
||||
lokalen Dateisystem persistiert (realisiert als JSON-Ablage). Nach jeder schreibenden
|
||||
Operation (Anlegen, Ändern, Löschen) meldet der `KundenVerwaltungsService` die Änderung
|
||||
über einen **`EreignisBus`** (Observer-Muster, Paket `gemeinsam`;
|
||||
`melde(DatenBereich.KUNDEN)`), den die Kundenansicht der Gruppe D abonniert und sich
|
||||
daraufhin automatisch aktualisiert.
|
||||
|
||||
### 7.1 Klassendiagramm
|
||||
|
||||
|
|
@ -363,8 +367,9 @@ mit ihren Attributen (Kapitel 6.1). Der `KundenVerwaltungsService` orchestriert
|
|||
Kundennummern, F-02), das `KundenRepository` (Persistenz, IF-01) und die von Gruppe A
|
||||
bereitgestellte Schnittstelle `KundenReferenzPruefung` (Löschsperre GR-04, F-09/F-10).
|
||||
Zusätzlich realisiert der `KundenVerwaltungsService` das Interface `KundenService`
|
||||
(lesender Zugriff für Gruppe A, F-14). Dokumente (Gruppe A) referenzieren einen `Kunde`
|
||||
ausschließlich über die Kundennummer (lose Kopplung).
|
||||
(lesender Zugriff für Gruppe A, F-14) und meldet Datenänderungen über den `EreignisBus`
|
||||
(Observer-Muster) an die abonnierte Kundenansicht der Gruppe D. Dokumente (Gruppe A)
|
||||
referenzieren einen `Kunde` ausschließlich über die Kundennummer (lose Kopplung).
|
||||
|
||||
### 7.2 Sequenzdiagramm
|
||||
|
||||
|
|
|
|||
|
|
@ -365,13 +365,17 @@ public interface ProduktService {
|
|||
|
||||
## 7. Systemarchitektur (logisch, grob)
|
||||
|
||||
Die Komponente folgt dem Muster *Model–View–Controller*: Die Views (Hauptfenster,
|
||||
Modulansichten, Wizard-Dialog) enthalten ausschließlich Darstellung; die Controller
|
||||
(`HauptController`, `StammdatenController`, `RechnungsWizardController`,
|
||||
`DokumentListenController`) kapseln Dialogführung und Vollständigkeitsprüfungen und rufen
|
||||
die Service-Schnittstellen der Gruppen A–C auf. Das UI-Zustandsmodell
|
||||
(`RechnungsWizardModel`, `Meldung`) ist frei von GUI-Framework-Klassen und damit im
|
||||
Modultest ohne Oberfläche prüfbar.
|
||||
Die Komponente folgt dem Muster *Model–View–Controller*: Die Views (das Hauptfenster
|
||||
`HauptFenster`, die Modulansichten `KundenPanel`/`ProduktPanel`/`DokumentListenPanel`, der
|
||||
Wizard-Dialog) enthalten die Darstellung; die Controller (`StammdatenController`,
|
||||
`RechnungsWizardController`, `DokumentListenController`) kapseln Dialogführung und
|
||||
Vollständigkeitsprüfungen und rufen die Service-Schnittstellen der Gruppen A–C auf. Das
|
||||
`HauptFenster` (ein `JFrame`) hält die Navigationsleiste und schaltet die Modulansichten
|
||||
über ein `CardLayout` um; die Verdrahtung von Panels, Controllern und Services erfolgt beim
|
||||
Programmstart (`Main`). Die Modulansichten abonnieren den gemeinsamen `EreignisBus`
|
||||
(Observer-Muster, Paket `gemeinsam`) und aktualisieren sich nach Datenänderungen der
|
||||
Gruppen A–C automatisch. Das UI-Zustandsmodell (`RechnungsWizardModel`, `Meldung`) ist frei
|
||||
von GUI-Framework-Klassen und damit im Modultest ohne Oberfläche prüfbar.
|
||||
|
||||
### 7.1 Klassendiagramm
|
||||
|
||||
|
|
@ -379,16 +383,18 @@ Modultest ohne Oberfläche prüfbar.
|
|||
|
||||
![Abbildung 1: UML-Klassendiagramm Programmoberfläche (Gruppe D)]
|
||||
|
||||
**Beschreibung zu Abbildung 1:** Das Klassendiagramm zeigt die Controller-Schicht der
|
||||
Oberfläche. Der `HauptController` verwaltet die Navigation (F-01, F-02) und erzeugt die
|
||||
Modul-Controller. Der `StammdatenController` bedient Listen-, Such- und Formularansichten
|
||||
für Kunden und Produkte und nutzt dazu `KundenService` (Gruppe C) und `ProduktService`
|
||||
(Gruppe B). Der `RechnungsWizardController` führt die Schrittfolge des Enums
|
||||
`WizardSchritt` über das `RechnungsWizardModel` (Komposition) und delegiert das Speichern
|
||||
an den `DokumentService` (Gruppe A). Der `DokumentListenController` stellt die
|
||||
Dokumentliste mit Statusfilter dar und bietet die Belegaktionen an (F-06–F-08, F-14,
|
||||
F-15). Fehler- und Erfolgsmeldungen werden einheitlich über die Klasse `Meldung`
|
||||
dargestellt (F-16, F-17).
|
||||
**Beschreibung zu Abbildung 1:** Das Klassendiagramm zeigt die View- und Controller-Schicht
|
||||
der Oberfläche. Das `HauptFenster` (ein `JFrame`) verwaltet die Navigation (F-01, F-02): es
|
||||
nimmt die drei Modulansichten (`KundenPanel`, `ProduktPanel`, `DokumentListenPanel`)
|
||||
entgegen und schaltet sie über ein `CardLayout` um. Der `StammdatenController` bedient
|
||||
Listen-, Such- und Formularansichten für Kunden und Produkte und nutzt dazu `KundenService`
|
||||
(Gruppe C) und `ProduktService` (Gruppe B). Der `RechnungsWizardController` führt die
|
||||
Schrittfolge des Enums `WizardSchritt` über das `RechnungsWizardModel` (Komposition) und
|
||||
delegiert das Speichern an den `DokumentService` (Gruppe A). Der `DokumentListenController`
|
||||
stellt die Dokumentliste mit Statusfilter dar und bietet die Belegaktionen an (F-06–F-08,
|
||||
F-14, F-15). Die Modulansichten abonnieren den gemeinsamen `EreignisBus` (Observer-Muster)
|
||||
und aktualisieren sich nach Datenänderungen selbsttätig. Fehler- und Erfolgsmeldungen werden
|
||||
einheitlich über die Klasse `Meldung` dargestellt (F-16, F-17).
|
||||
|
||||
### 7.2 Sequenzdiagramm
|
||||
|
||||
|
|
|
|||
Binary file not shown.
|
After Width: | Height: | Size: 227 KiB |
|
|
@ -0,0 +1,173 @@
|
|||
@startuml klassendiagramm_dokumentenzyklus
|
||||
' UML-Klassendiagramm Dokumentenzyklus (Pflichtenheft Gruppe A, Abschnitt 7.1)
|
||||
' Layout-Engine Smetana -> kein Graphviz erforderlich.
|
||||
!pragma layout smetana
|
||||
|
||||
skinparam shadowing false
|
||||
skinparam classAttributeIconSize 0
|
||||
skinparam linetype ortho
|
||||
hide empty members
|
||||
|
||||
title UML-Klassendiagramm — Dokumentenzyklus (Gruppe A)
|
||||
|
||||
' ===================== Domänenmodell =====================
|
||||
|
||||
abstract class Dokument {
|
||||
- belegnummer : String
|
||||
- datum : LocalDate
|
||||
- kundenReferenz : String
|
||||
- kundeName : String
|
||||
- kundeAnschrift : String
|
||||
- status : DokumentStatus
|
||||
- vorgaengerNr : String
|
||||
- summeNetto : BigDecimal
|
||||
- summeSteuer : BigDecimal
|
||||
- summeBrutto : BigDecimal
|
||||
+ {abstract} belegtyp() : Belegtyp
|
||||
+ setzePositionen(positionen : List<Dokumentposition>)
|
||||
+ berechneSummen()
|
||||
+ versende()
|
||||
+ pruefeAenderbar()
|
||||
}
|
||||
|
||||
class Angebot {
|
||||
- gueltigBis : LocalDate
|
||||
}
|
||||
|
||||
class Auftragsbestaetigung {
|
||||
}
|
||||
|
||||
class Lieferschein {
|
||||
- lieferdatum : LocalDate
|
||||
}
|
||||
|
||||
class Rechnung {
|
||||
- leistungsdatum : LocalDate
|
||||
- zahlungsziel : LocalDate
|
||||
- storniertAm : LocalDate
|
||||
- storniertVon : String
|
||||
+ storniere(datum : LocalDate, benutzer : String)
|
||||
}
|
||||
|
||||
class Dokumentposition {
|
||||
- produktReferenz : String
|
||||
- bezeichnung : String
|
||||
- menge : int
|
||||
- einzelpreisNetto : BigDecimal
|
||||
- steuersatz : BigDecimal
|
||||
- positionssummeNetto : BigDecimal
|
||||
+ getSteuerbetrag() : BigDecimal
|
||||
+ getPositionssummeBrutto() : BigDecimal
|
||||
}
|
||||
|
||||
enum DokumentStatus {
|
||||
ENTWURF
|
||||
OFFEN
|
||||
VERSENDET
|
||||
STORNIERT
|
||||
}
|
||||
|
||||
enum Belegtyp {
|
||||
ANGEBOT
|
||||
AUFTRAGSBESTAETIGUNG
|
||||
LIEFERSCHEIN
|
||||
RECHNUNG
|
||||
}
|
||||
|
||||
' Vererbung der vier Belegtypen
|
||||
Dokument <|-- Angebot
|
||||
Dokument <|-- Auftragsbestaetigung
|
||||
Dokument <|-- Lieferschein
|
||||
Dokument <|-- Rechnung
|
||||
|
||||
' Komposition: ein Dokument besteht aus 1..* Positionen
|
||||
Dokument "1" *-- "1..*" Dokumentposition : positionen
|
||||
|
||||
Dokument --> DokumentStatus : status
|
||||
Dokument ..> Belegtyp : belegtyp()
|
||||
|
||||
' ===================== Service-Schicht =====================
|
||||
|
||||
interface DokumentService <<interface>> {
|
||||
+ erstelleAngebot(...) : Angebot
|
||||
+ erstelleAuftragsbestaetigung(...) : Auftragsbestaetigung
|
||||
+ erstelleLieferschein(...) : Lieferschein
|
||||
+ erstelleRechnung(...) : Rechnung
|
||||
+ erzeugeFolgebeleg(belegnummer : String) : Dokument
|
||||
+ storniere(rechnungsnummer : String)
|
||||
+ berechneSummen(...) : Summen
|
||||
+ exportierePdf(belegnummer : String, zielDatei : Path)
|
||||
}
|
||||
|
||||
class StandardDokumentService {
|
||||
}
|
||||
|
||||
interface BelegnummernGenerator <<interface>> {
|
||||
+ naechsteNummer(typ : Belegtyp, jahr : int) : String
|
||||
}
|
||||
|
||||
interface DokumentRepository <<interface>> {
|
||||
+ speichere(dokument : Dokument) : Dokument
|
||||
+ findeNachNummer(belegnummer : String) : Dokument
|
||||
+ alle() : List<Dokument>
|
||||
}
|
||||
|
||||
interface PdfExporter <<interface>> {
|
||||
+ exportiere(dokument : Dokument, zielDatei : Path)
|
||||
}
|
||||
|
||||
class EreignisBus {
|
||||
+ abonniere(bereich : DatenBereich, beobachter : Runnable)
|
||||
+ melde(bereich : DatenBereich)
|
||||
}
|
||||
|
||||
enum DatenBereich {
|
||||
KUNDEN
|
||||
PRODUKTE
|
||||
DOKUMENTE
|
||||
}
|
||||
|
||||
' DTOs (Eingabe/Ausgabe des Service)
|
||||
class Positionsangabe <<record>> {
|
||||
+ produktnummer : String
|
||||
+ menge : int
|
||||
}
|
||||
|
||||
class Summen <<record>> {
|
||||
+ netto : BigDecimal
|
||||
+ steuer : BigDecimal
|
||||
+ brutto : BigDecimal
|
||||
}
|
||||
|
||||
DokumentService <|.. StandardDokumentService
|
||||
|
||||
StandardDokumentService ..> BelegnummernGenerator
|
||||
StandardDokumentService ..> DokumentRepository
|
||||
StandardDokumentService ..> PdfExporter
|
||||
StandardDokumentService ..> EreignisBus
|
||||
StandardDokumentService ..> Dokument : erzeugt
|
||||
EreignisBus ..> DatenBereich
|
||||
DokumentService ..> Positionsangabe
|
||||
DokumentService ..> Summen
|
||||
|
||||
' ===================== Externe Komponenten (lose Kopplung) =====================
|
||||
|
||||
interface KundenService <<extern (Gruppe C)>> {
|
||||
+ findeKunde(kundennummer : String) : Kunde
|
||||
}
|
||||
|
||||
interface ProduktService <<extern (Gruppe B)>> {
|
||||
+ findeProdukt(produktnummer : String) : Produkt
|
||||
}
|
||||
|
||||
class Kunde <<extern (Gruppe C)>>
|
||||
class Produkt <<extern (Gruppe B)>>
|
||||
|
||||
StandardDokumentService ..> KundenService
|
||||
StandardDokumentService ..> ProduktService
|
||||
|
||||
' Referenz nur über die Stammdatennummer (lose Kopplung)
|
||||
Dokument ..> Kunde : "über Kundennummer"
|
||||
Dokumentposition ..> Produkt : "über Produktnummer"
|
||||
|
||||
@enduml
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 105 KiB |
|
|
@ -0,0 +1,81 @@
|
|||
@startuml sequenz_rechnung_erstellen
|
||||
' UML-Sequenzdiagramm "Rechnung erstellen" (Pflichtenheft Gruppe A, Abschnitt 7.2)
|
||||
' Ablauf gemäß StandardDokumentService.erstelleRechnung(...) und exportierePdf(...).
|
||||
|
||||
skinparam shadowing false
|
||||
skinparam sequenceMessageAlign center
|
||||
hide footbox
|
||||
|
||||
title UML-Sequenzdiagramm — „Rechnung erstellen" (Gruppe A)
|
||||
|
||||
participant "GUI\n(Gruppe D)" as GUI
|
||||
participant "dokumentService :\nStandardDokumentService" as DS
|
||||
participant "kundenService :\nKundenService" as KS
|
||||
participant "produktService :\nProduktService" as PS
|
||||
participant "nummernGenerator :\nBelegnummernGenerator" as NG
|
||||
participant "repository :\nDokumentRepository" as REPO
|
||||
participant "ereignisBus :\nEreignisBus" as EB
|
||||
|
||||
GUI -> DS : erstelleRechnung(kundenNr, positionen,\nrechnungsdatum, zahlungsziel)
|
||||
activate DS
|
||||
|
||||
DS -> KS : findeKunde(kundenNr)
|
||||
activate KS
|
||||
KS --> DS : kunde
|
||||
deactivate KS
|
||||
|
||||
loop für jede Positionsangabe
|
||||
DS -> PS : findeProdukt(produktnummer)
|
||||
activate PS
|
||||
PS --> DS : produkt
|
||||
deactivate PS
|
||||
DS -> DS : new Dokumentposition(...)
|
||||
note right of DS : Preis- und Steuersatz-Snapshot\ndes Produkts (GR-03, F-23)
|
||||
end
|
||||
|
||||
DS -> NG : naechsteNummer(RECHNUNG, jahr)
|
||||
activate NG
|
||||
NG --> DS : "R-2026-000124"
|
||||
deactivate NG
|
||||
|
||||
DS -> DS : zahlungsziel = rechnungsdatum + 14 Tage\n(falls nicht angegeben, GR-06)
|
||||
|
||||
create participant "rechnung :\nRechnung" as R
|
||||
DS -> R : «create»
|
||||
DS -> R : setzePositionen(positionen)
|
||||
activate R
|
||||
R -> R : berechneSummen()
|
||||
deactivate R
|
||||
DS -> R : setzeStatus(OFFEN)
|
||||
|
||||
DS -> REPO : speichere(rechnung)
|
||||
activate REPO
|
||||
REPO --> DS : rechnung
|
||||
deactivate REPO
|
||||
|
||||
DS -> EB : melde(DOKUMENTE)
|
||||
activate EB
|
||||
note right of EB : benachrichtigt die abonnierten\nModulansichten (Observer-Muster)
|
||||
EB --> DS
|
||||
deactivate EB
|
||||
|
||||
DS --> GUI : rechnung
|
||||
deactivate DS
|
||||
|
||||
group Separater Aufruf: PDF-Export (F-15, IF-01)
|
||||
participant "pdfExporter :\nPdfExporter" as PDF
|
||||
GUI -> DS : exportierePdf(belegnummer, zielDatei)
|
||||
activate DS
|
||||
DS -> REPO : findeNachNummer(belegnummer)
|
||||
activate REPO
|
||||
REPO --> DS : rechnung
|
||||
deactivate REPO
|
||||
DS -> PDF : exportiere(rechnung, zielDatei)
|
||||
activate PDF
|
||||
PDF --> DS
|
||||
deactivate PDF
|
||||
DS --> GUI : PDF im lokalen Dateisystem
|
||||
deactivate DS
|
||||
end
|
||||
|
||||
@enduml
|
||||
Binary file not shown.
Loading…
Reference in New Issue