Ergänzung von Diagrammen Gruppe A

main
Lucas Strubel 2026-06-13 11:04:50 +02:00
parent 3846ba0cde
commit c89e9a5c6f
10 changed files with 367 additions and 55 deletions

View File

@ -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)]
![Abbildung 1: UML-Klassendiagramm Dokumentenzyklus (Gruppe A)](diagramme/klassendiagramm_dokumentenzyklus.png)
**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)]
![Abbildung 2: UML-Sequenzdiagramm „Rechnung erstellen" (Gruppe A)](diagramme/sequenz_rechnung_erstellen.png)
**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.

View File

@ -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

View File

@ -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

View File

@ -365,13 +365,17 @@ public interface ProduktService {
## 7. Systemarchitektur (logisch, grob)
Die Komponente folgt dem Muster *ModelViewController*: 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 AC 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 *ModelViewController*: 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 AC 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 AC 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-06F-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-06F-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

View File

@ -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

View File

@ -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

BIN
tools/plantuml.jar 100644

Binary file not shown.