diff --git a/out/belegworkflow/Angebot.class b/out/belegworkflow/Angebot.class new file mode 100644 index 0000000..ef085b4 Binary files /dev/null and b/out/belegworkflow/Angebot.class differ diff --git a/out/belegworkflow/AngebotStatus.class b/out/belegworkflow/AngebotStatus.class new file mode 100644 index 0000000..7b6c88f Binary files /dev/null and b/out/belegworkflow/AngebotStatus.class differ diff --git a/out/belegworkflow/BelegnummernGenerator.class b/out/belegworkflow/BelegnummernGenerator.class new file mode 100644 index 0000000..1ac625a Binary files /dev/null and b/out/belegworkflow/BelegnummernGenerator.class differ diff --git a/out/belegworkflow/BelegworkflowService.class b/out/belegworkflow/BelegworkflowService.class new file mode 100644 index 0000000..b6376cc Binary files /dev/null and b/out/belegworkflow/BelegworkflowService.class differ diff --git a/out/belegworkflow/Dokument.class b/out/belegworkflow/Dokument.class new file mode 100644 index 0000000..e19a186 Binary files /dev/null and b/out/belegworkflow/Dokument.class differ diff --git a/out/belegworkflow/Dokumentposition.class b/out/belegworkflow/Dokumentposition.class new file mode 100644 index 0000000..c7339be Binary files /dev/null and b/out/belegworkflow/Dokumentposition.class differ diff --git a/out/belegworkflow/Rechnung.class b/out/belegworkflow/Rechnung.class new file mode 100644 index 0000000..3f1d908 Binary files /dev/null and b/out/belegworkflow/Rechnung.class differ diff --git a/out/belegworkflow/RechnungStatus.class b/out/belegworkflow/RechnungStatus.class new file mode 100644 index 0000000..6de0d95 Binary files /dev/null and b/out/belegworkflow/RechnungStatus.class differ diff --git a/out/kundenverwaltung/Main.class b/out/kundenverwaltung/Main.class index 9266de6..1ea4d40 100644 Binary files a/out/kundenverwaltung/Main.class and b/out/kundenverwaltung/Main.class differ diff --git a/src/main/java/belegworkflow/Angebot.java b/src/main/java/belegworkflow/Angebot.java new file mode 100644 index 0000000..783a78a --- /dev/null +++ b/src/main/java/belegworkflow/Angebot.java @@ -0,0 +1,33 @@ +package belegworkflow; + +import java.time.LocalDate; +import java.util.List; + +public class Angebot extends Dokument { + + private LocalDate gueltigBis; + private AngebotStatus status; + + public Angebot(String belegnummer, LocalDate datum, String kundenReferenz, + List positionen, LocalDate gueltigBis) { + super(belegnummer, datum, kundenReferenz, positionen); + this.gueltigBis = gueltigBis; + this.status = AngebotStatus.OFFEN; + } + + public LocalDate getGueltigBis() { return gueltigBis; } + public AngebotStatus getStatus() { return status; } + + public void setStatus(AngebotStatus status) { + this.status = status; + } + + @Override + public String toString() { + return String.format("[%s] Angebot | Kunde: %s | Datum: %s | Gueltig bis: %s | Status: %s\n%s\n%s", + belegnummer, kundenReferenz, datum, gueltigBis, status, + positionen.stream().map(Dokumentposition::toString) + .reduce("", (a, b) -> a + "\n" + b), + getSummenAnzeige()); + } +} \ No newline at end of file diff --git a/src/main/java/belegworkflow/AngebotStatus.java b/src/main/java/belegworkflow/AngebotStatus.java new file mode 100644 index 0000000..63b8a3c --- /dev/null +++ b/src/main/java/belegworkflow/AngebotStatus.java @@ -0,0 +1,7 @@ +package belegworkflow; + +public enum AngebotStatus { + OFFEN, + UEBERFUEHRT, + VERWORFEN +} \ No newline at end of file diff --git a/src/main/java/belegworkflow/BelegnummernGenerator.java b/src/main/java/belegworkflow/BelegnummernGenerator.java new file mode 100644 index 0000000..f890b06 --- /dev/null +++ b/src/main/java/belegworkflow/BelegnummernGenerator.java @@ -0,0 +1,53 @@ +package belegworkflow; + +import java.io.*; +import java.nio.file.*; + +public class BelegnummernGenerator { + + private static final String ANGEBOT_COUNTER = "data/angebot_counter.txt"; + private static final String RECHNUNG_COUNTER = "data/rechnung_counter.txt"; + + private int angebotCounter; + private int rechnungCounter; + + public BelegnummernGenerator() { + this.angebotCounter = ladeCounter(ANGEBOT_COUNTER); + this.rechnungCounter = ladeCounter(RECHNUNG_COUNTER); + } + + // Nächste lückenlose Angebotsnummer (GR-01) + public String naechsteAngebotsnummer(int jahr) { + angebotCounter++; + speichereCounter(ANGEBOT_COUNTER, angebotCounter); + return String.format("AN-%d-%06d", jahr, angebotCounter); + } + + // Nächste lückenlose Rechnungsnummer (GR-01, F-07) + public String naechsteRechnungsnummer(int jahr) { + rechnungCounter++; + speichereCounter(RECHNUNG_COUNTER, rechnungCounter); + return String.format("R-%d-%06d", jahr, rechnungCounter); + } + + private int ladeCounter(String datei) { + try { + Path path = Path.of(datei); + if (Files.exists(path)) { + return Integer.parseInt(Files.readString(path).trim()); + } + } catch (IOException e) { + System.err.println("Counter konnte nicht geladen werden: " + datei); + } + return 0; + } + + private void speichereCounter(String datei, int wert) { + try { + Files.createDirectories(Path.of("data")); + Files.writeString(Path.of(datei), String.valueOf(wert)); + } catch (IOException e) { + System.err.println("Counter konnte nicht gespeichert werden: " + datei); + } + } +} \ No newline at end of file diff --git a/src/main/java/belegworkflow/BelegworkflowService.java b/src/main/java/belegworkflow/BelegworkflowService.java new file mode 100644 index 0000000..6852208 --- /dev/null +++ b/src/main/java/belegworkflow/BelegworkflowService.java @@ -0,0 +1,191 @@ +package belegworkflow; + +import java.io.*; +import java.nio.file.*; +import java.time.LocalDate; +import java.util.*; + +public class BelegworkflowService { + + private static final String ANGEBOTE_FILE = "data/angebote.csv"; + private static final String RECHNUNGEN_FILE = "data/rechnungen.csv"; + + private List angebote; + private List rechnungen; + private BelegnummernGenerator generator; + + public BelegworkflowService() throws IOException { + this.angebote = new ArrayList<>(); + this.rechnungen = new ArrayList<>(); + this.generator = new BelegnummernGenerator(); + Files.createDirectories(Path.of("data")); + ladeAngebote(); + ladeRechnungen(); + } + + // Erstellt ein neues Angebot (F-01, F-02, F-03, F-04) + public Angebot erstelleAngebot(String kundenId, List positionen, + LocalDate gueltigBis) { + if (kundenId == null || kundenId.isBlank()) { + System.out.println("Fehler: Kunden-ID darf nicht leer sein."); + return null; + } + if (positionen == null || positionen.isEmpty()) { + System.out.println("Fehler: Mindestens eine Position erforderlich."); + return null; + } + + String nr = generator.naechsteAngebotsnummer(LocalDate.now().getYear()); + Angebot angebot = new Angebot(nr, LocalDate.now(), kundenId, positionen, gueltigBis); + angebote.add(angebot); + speichereAngebote(); + System.out.println("Angebot erfolgreich erstellt: " + nr); + return angebot; + } + + // Erstellt eine Rechnung aus einem Angebot (F-05, F-06, F-07, F-08) + public Rechnung erstelleRechnungAusAngebot(String angebotsNr, LocalDate rechnungsdatum, + LocalDate leistungsdatum, LocalDate zahlungsziel) { + Angebot angebot = findeAngebot(angebotsNr); + if (angebot == null) { + System.out.println("Fehler: Angebot " + angebotsNr + " nicht gefunden."); + return null; + } + if (angebot.getStatus() != AngebotStatus.OFFEN) { + System.out.println("Fehler: Angebot ist nicht mehr offen."); + return null; + } + + String nr = generator.naechsteRechnungsnummer(LocalDate.now().getYear()); + Rechnung rechnung = new Rechnung(nr, LocalDate.now(), angebot.getKundenReferenz(), + angebot.getPositionen(), rechnungsdatum, leistungsdatum, zahlungsziel, angebotsNr); + + // Angebot als überführt markieren (F-05) + angebot.setStatus(AngebotStatus.UEBERFUEHRT); + rechnungen.add(rechnung); + speichereAngebote(); + speichereRechnungen(); + System.out.println("Rechnung erfolgreich erstellt: " + nr); + return rechnung; + } + + // Festschreiben einer Rechnung (F-10) + public void finalisiereRechnung(String rechnungsNr) { + Rechnung rechnung = findeRechnung(rechnungsNr); + if (rechnung == null) { + System.out.println("Fehler: Rechnung " + rechnungsNr + " nicht gefunden."); + return; + } + rechnung.festschreiben(); + speichereRechnungen(); + System.out.println("Rechnung " + rechnungsNr + " wurde festgeschrieben."); + } + + // Prüft ob Kunde in einem Beleg referenziert wird (F-12) + public boolean istKundeReferenziert(String kundenId) { + return angebote.stream().anyMatch(a -> a.getKundenReferenz().equals(kundenId)) || + rechnungen.stream().anyMatch(r -> r.getKundenReferenz().equals(kundenId)); + } + + // Prüft ob Produkt in einem Beleg referenziert wird (F-12) + public boolean istProduktReferenziert(String produktId) { + return angebote.stream().anyMatch(a -> a.getPositionen().stream() + .anyMatch(p -> p.getProduktReferenz().equals(produktId))) || + rechnungen.stream().anyMatch(r -> r.getPositionen().stream() + .anyMatch(p -> p.getProduktReferenz().equals(produktId))); + } + + public List alleAngebote() { return new ArrayList<>(angebote); } + public List alleRechnungen() { return new ArrayList<>(rechnungen); } + + public Angebot findeAngebot(String nr) { + return angebote.stream().filter(a -> a.getBelegnummer().equals(nr)).findFirst().orElse(null); + } + public Rechnung findeRechnung(String nr) { + return rechnungen.stream().filter(r -> r.getBelegnummer().equals(nr)).findFirst().orElse(null); + } + + // Einfache CSV Persistenz für Angebote + private void speichereAngebote() { + try { + StringBuilder sb = new StringBuilder(); + for (Angebot a : angebote) { + sb.append(a.getBelegnummer()).append(";") + .append(a.getDatum()).append(";") + .append(a.getKundenReferenz()).append(";") + .append(a.getGueltigBis()).append(";") + .append(a.getStatus()).append(";") + .append(a.getSummeNetto()).append(";") + .append(a.getSummeSteuer()).append(";") + .append(a.getSummeBrutto()).append("\n"); + } + Files.writeString(Path.of(ANGEBOTE_FILE), sb.toString()); + } catch (IOException e) { + System.err.println("Fehler beim Speichern der Angebote: " + e.getMessage()); + } + } + + private void ladeAngebote() { + try { + Path path = Path.of(ANGEBOTE_FILE); + if (!Files.exists(path)) return; + // Vereinfachtes Laden - nur Metadaten ohne Positionen + List zeilen = Files.readAllLines(path); + for (String zeile : zeilen) { + if (zeile.isBlank()) continue; + String[] t = zeile.split(";", -1); + if (t.length < 8) continue; + Angebot a = new Angebot(t[0], LocalDate.parse(t[1]), t[2], + new ArrayList<>(), LocalDate.parse(t[3])); + a.setStatus(AngebotStatus.valueOf(t[4])); + angebote.add(a); + } + } catch (IOException e) { + System.err.println("Fehler beim Laden der Angebote: " + e.getMessage()); + } + } + + private void speichereRechnungen() { + try { + StringBuilder sb = new StringBuilder(); + for (Rechnung r : rechnungen) { + sb.append(r.getBelegnummer()).append(";") + .append(r.getDatum()).append(";") + .append(r.getKundenReferenz()).append(";") + .append(r.getRechnungsdatum()).append(";") + .append(r.getLeistungsdatum()).append(";") + .append(r.getZahlungsziel()).append(";") + .append(r.getAngebotsNr()).append(";") + .append(r.getStatus()).append(";") + .append(r.isFestgeschrieben()).append(";") + .append(r.getSummeNetto()).append(";") + .append(r.getSummeSteuer()).append(";") + .append(r.getSummeBrutto()).append("\n"); + } + Files.writeString(Path.of(RECHNUNGEN_FILE), sb.toString()); + } catch (IOException e) { + System.err.println("Fehler beim Speichern der Rechnungen: " + e.getMessage()); + } + } + + private void ladeRechnungen() { + try { + Path path = Path.of(RECHNUNGEN_FILE); + if (!Files.exists(path)) return; + List zeilen = Files.readAllLines(path); + for (String zeile : zeilen) { + if (zeile.isBlank()) continue; + String[] t = zeile.split(";", -1); + if (t.length < 12) continue; + Rechnung r = new Rechnung(t[0], LocalDate.parse(t[1]), t[2], + new ArrayList<>(), LocalDate.parse(t[3]), LocalDate.parse(t[4]), + LocalDate.parse(t[5]), t[6]); + r.setStatus(RechnungStatus.valueOf(t[7])); + if (Boolean.parseBoolean(t[8])) r.festschreiben(); + rechnungen.add(r); + } + } catch (IOException e) { + System.err.println("Fehler beim Laden der Rechnungen: " + e.getMessage()); + } + } +} \ No newline at end of file diff --git a/src/main/java/belegworkflow/Dokument.java b/src/main/java/belegworkflow/Dokument.java new file mode 100644 index 0000000..25ea754 --- /dev/null +++ b/src/main/java/belegworkflow/Dokument.java @@ -0,0 +1,63 @@ +package belegworkflow; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.time.LocalDate; +import java.util.List; + +public abstract class Dokument { + protected String belegnummer; + protected LocalDate datum; + protected String kundenReferenz; + protected List positionen; + protected BigDecimal summeNetto; + protected BigDecimal summeSteuer; + protected BigDecimal summeBrutto; + protected boolean festgeschrieben; + + public Dokument(String belegnummer, LocalDate datum, String kundenReferenz, + List positionen) { + this.belegnummer = belegnummer; + this.datum = datum; + this.kundenReferenz = kundenReferenz; + this.positionen = positionen; + this.festgeschrieben = false; + berechnesSummen(); + } + + // Berechnet Netto-, Steuer- und Bruttosumme (F-03, F-09, GR-06) + protected void berechnesSummen() { + summeNetto = BigDecimal.ZERO; + summeSteuer = BigDecimal.ZERO; + + for (Dokumentposition pos : positionen) { + summeNetto = summeNetto.add(pos.getPositionssummeNetto()); + BigDecimal steuer = pos.getPositionssummeNetto() + .multiply(pos.getSteuersatz()) + .setScale(2, RoundingMode.HALF_UP); + summeSteuer = summeSteuer.add(steuer); + } + + summeNetto = summeNetto.setScale(2, RoundingMode.HALF_UP); + summeSteuer = summeSteuer.setScale(2, RoundingMode.HALF_UP); + summeBrutto = summeNetto.add(summeSteuer).setScale(2, RoundingMode.HALF_UP); + } + + public String getBelegnummer() { return belegnummer; } + public LocalDate getDatum() { return datum; } + public String getKundenReferenz() { return kundenReferenz; } + public List getPositionen() { return positionen; } + public BigDecimal getSummeNetto() { return summeNetto; } + public BigDecimal getSummeSteuer() { return summeSteuer; } + public BigDecimal getSummeBrutto() { return summeBrutto; } + public boolean isFestgeschrieben() { return festgeschrieben; } + + public void festschreiben() { + this.festgeschrieben = true; + } + + public String getSummenAnzeige() { + return String.format("Netto: %.2f EUR | MwSt: %.2f EUR | Brutto: %.2f EUR", + summeNetto, summeSteuer, summeBrutto); + } +} \ No newline at end of file diff --git a/src/main/java/belegworkflow/Dokumentposition.java b/src/main/java/belegworkflow/Dokumentposition.java new file mode 100644 index 0000000..16832ed --- /dev/null +++ b/src/main/java/belegworkflow/Dokumentposition.java @@ -0,0 +1,39 @@ +package belegworkflow; + +import java.math.BigDecimal; +import java.math.RoundingMode; + +public class Dokumentposition { + private String produktReferenz; + private String bezeichnung; + private int menge; + private BigDecimal einzelpreisNetto; + private BigDecimal steuersatz; + private BigDecimal positionssummeNetto; + + public Dokumentposition(String produktReferenz, String bezeichnung, + int menge, BigDecimal einzelpreisNetto, BigDecimal steuersatz) { + this.produktReferenz = produktReferenz; + this.bezeichnung = bezeichnung; + this.menge = menge; + this.einzelpreisNetto = einzelpreisNetto.setScale(2, RoundingMode.HALF_UP); + this.steuersatz = steuersatz.setScale(2, RoundingMode.HALF_UP); + this.positionssummeNetto = einzelpreisNetto + .multiply(new BigDecimal(menge)) + .setScale(2, RoundingMode.HALF_UP); + } + + public String getProduktReferenz() { return produktReferenz; } + public String getBezeichnung() { return bezeichnung; } + public int getMenge() { return menge; } + public BigDecimal getEinzelpreisNetto() { return einzelpreisNetto; } + public BigDecimal getSteuersatz() { return steuersatz; } + public BigDecimal getPositionssummeNetto(){ return positionssummeNetto; } + + @Override + public String toString() { + return String.format(" %s x%d | %.2f EUR (netto) | MwSt: %.0f%%", + bezeichnung, menge, einzelpreisNetto, + steuersatz.multiply(new BigDecimal("100"))); + } +} \ No newline at end of file diff --git a/src/main/java/belegworkflow/Rechnung.java b/src/main/java/belegworkflow/Rechnung.java new file mode 100644 index 0000000..5a5d8a1 --- /dev/null +++ b/src/main/java/belegworkflow/Rechnung.java @@ -0,0 +1,50 @@ +package belegworkflow; + +import java.time.LocalDate; +import java.util.List; + +public class Rechnung extends Dokument { + + private LocalDate rechnungsdatum; + private LocalDate leistungsdatum; + private LocalDate zahlungsziel; + private String angebotsNr; + private RechnungStatus status; + + public Rechnung(String belegnummer, LocalDate datum, String kundenReferenz, + List positionen, LocalDate rechnungsdatum, + LocalDate leistungsdatum, LocalDate zahlungsziel, String angebotsNr) { + super(belegnummer, datum, kundenReferenz, positionen); + this.rechnungsdatum = rechnungsdatum; + this.leistungsdatum = leistungsdatum; + this.zahlungsziel = zahlungsziel; + this.angebotsNr = angebotsNr; + this.status = RechnungStatus.OFFEN; + } + + public LocalDate getRechnungsdatum() { return rechnungsdatum; } + public LocalDate getLeistungsdatum() { return leistungsdatum; } + public LocalDate getZahlungsziel() { return zahlungsziel; } + public String getAngebotsNr() { return angebotsNr; } + public RechnungStatus getStatus() { return status; } + + public void setStatus(RechnungStatus status) { + // Schreibschutz prüfen (F-10) + if (this.festgeschrieben) { + System.out.println("Fehler: Festgeschriebene Rechnung kann nicht geaendert werden."); + return; + } + this.status = status; + } + + @Override + public String toString() { + return String.format( + "[%s] Rechnung | Kunde: %s | Datum: %s | Leistung: %s | Zahlung bis: %s | Angebot: %s | Status: %s\n%s\n%s", + belegnummer, kundenReferenz, rechnungsdatum, leistungsdatum, + zahlungsziel, angebotsNr, status, + positionen.stream().map(Dokumentposition::toString) + .reduce("", (a, b) -> a + "\n" + b), + getSummenAnzeige()); + } +} \ No newline at end of file diff --git a/src/main/java/belegworkflow/RechnungStatus.java b/src/main/java/belegworkflow/RechnungStatus.java new file mode 100644 index 0000000..f8c0b8e --- /dev/null +++ b/src/main/java/belegworkflow/RechnungStatus.java @@ -0,0 +1,6 @@ +package belegworkflow; + +public enum RechnungStatus { + OFFEN, + BEZAHLT +} \ No newline at end of file diff --git a/src/main/java/kundenverwaltung/Main.java b/src/main/java/kundenverwaltung/Main.java index 8eee9b2..3b80514 100644 --- a/src/main/java/kundenverwaltung/Main.java +++ b/src/main/java/kundenverwaltung/Main.java @@ -2,9 +2,12 @@ package kundenverwaltung; import bestandsmanagement.Produkt; import bestandsmanagement.ProduktServiceImpl; +import belegworkflow.*; import java.io.IOException; import java.math.BigDecimal; +import java.time.LocalDate; +import java.util.ArrayList; import java.util.List; import java.util.Scanner; @@ -12,12 +15,14 @@ public class Main { private static KundenServiceImpl kundenService; private static ProduktServiceImpl produktService; + private static BelegworkflowService belegService; private static Scanner scanner = new Scanner(System.in); public static void main(String[] args) { try { kundenService = new KundenServiceImpl(); produktService = new ProduktServiceImpl(); + belegService = new BelegworkflowService(); System.out.println("==========================================="); System.out.println(" Fakturierungsanwendung - Team 3"); System.out.println("==========================================="); @@ -32,19 +37,16 @@ public class Main { System.out.println("\n=== HAUPTMENUE ==="); System.out.println("1. Kundenverwaltung"); System.out.println("2. Bestandsmanagement"); + System.out.println("3. Belegworkflow"); System.out.println("0. Beenden"); System.out.print("Auswahl: "); - String eingabe = scanner.nextLine().trim(); - - switch (eingabe) { + switch (scanner.nextLine().trim()) { case "1" -> kundenmenue(); case "2" -> produktmenue(); - case "0" -> { - System.out.println("Programm beendet."); - return; - } - default -> System.out.println("Ungueltige Eingabe."); + case "3" -> belegmenue(); + case "0" -> { System.out.println("Programm beendet."); return; } + default -> System.out.println("Ungueltige Eingabe."); } } } @@ -70,7 +72,7 @@ public class Main { case "5" -> kundeLoschen(); case "6" -> transaktionshistorie(); case "0" -> { return; } - default -> System.out.println("Ungueltige Eingabe."); + default -> System.out.println("Ungueltige Eingabe."); } } } @@ -180,7 +182,7 @@ public class Main { case "4" -> artikelBearbeiten(); case "5" -> artikelLoeschen(); case "0" -> { return; } - default -> System.out.println("Ungueltige Eingabe."); + default -> System.out.println("Ungueltige Eingabe."); } } } @@ -253,4 +255,105 @@ public class Main { System.out.print("Artikel-ID: "); produktService.produktLoeschen(scanner.nextLine()); } + + // ─── BELEGWORKFLOW ────────────────────────────────────────────── + private static void belegmenue() { + while (true) { + System.out.println("\n--- BELEGWORKFLOW ---"); + System.out.println("1. Angebot erstellen"); + System.out.println("2. Alle Angebote anzeigen"); + System.out.println("3. Rechnung aus Angebot erstellen"); + System.out.println("4. Alle Rechnungen anzeigen"); + System.out.println("5. Rechnung festschreiben"); + System.out.println("0. Zurueck"); + System.out.print("Auswahl: "); + + switch (scanner.nextLine().trim()) { + case "1" -> angebotErstellen(); + case "2" -> alleAngeboteAnzeigen(); + case "3" -> rechnungAusAngebot(); + case "4" -> alleRechnungenAnzeigen(); + case "5" -> rechnungFestschreiben(); + case "0" -> { return; } + default -> System.out.println("Ungueltige Eingabe."); + } + } + } + + private static void angebotErstellen() { + System.out.println("\n--- ANGEBOT ERSTELLEN ---"); + System.out.print("Kunden-ID: "); + String kundenId = scanner.nextLine(); + + List positionen = new ArrayList<>(); + while (true) { + System.out.println("Position hinzufuegen (Enter zum Beenden):"); + System.out.print("Produkt-ID (oder Enter zum Beenden): "); + String produktId = scanner.nextLine(); + if (produktId.isBlank()) break; + + Produkt produkt = produktService.findeProdukt(produktId); + if (produkt == null) { + System.out.println("Produkt nicht gefunden."); + continue; + } + + System.out.print("Menge: "); + int menge = Integer.parseInt(scanner.nextLine().trim()); + + positionen.add(new Dokumentposition( + produkt.getProduktId(), + produkt.getBezeichnung(), + menge, + produkt.getNettoEinzelpreis(), + produkt.getMehrwertsteuersatz() + )); + System.out.println("Position hinzugefuegt: " + produkt.getBezeichnung()); + } + + if (positionen.isEmpty()) { + System.out.println("Fehler: Mindestens eine Position erforderlich."); + return; + } + + System.out.print("Gueltig bis (YYYY-MM-DD): "); + LocalDate gueltigBis = LocalDate.parse(scanner.nextLine()); + belegService.erstelleAngebot(kundenId, positionen, gueltigBis); + } + + private static void alleAngeboteAnzeigen() { + System.out.println("\n--- ALLE ANGEBOTE ---"); + List angebote = belegService.alleAngebote(); + if (angebote.isEmpty()) { System.out.println("Keine Angebote vorhanden."); return; } + angebote.forEach(a -> System.out.println(a.getBelegnummer() + " | Kunde: " + + a.getKundenReferenz() + " | Status: " + a.getStatus())); + } + + private static void rechnungAusAngebot() { + System.out.println("\n--- RECHNUNG AUS ANGEBOT ---"); + System.out.print("Angebotsnummer: "); + String angebotsNr = scanner.nextLine(); + System.out.print("Rechnungsdatum (YYYY-MM-DD): "); + LocalDate rechnungsdatum = LocalDate.parse(scanner.nextLine()); + System.out.print("Leistungsdatum (YYYY-MM-DD): "); + LocalDate leistungsdatum = LocalDate.parse(scanner.nextLine()); + System.out.print("Zahlungsziel (YYYY-MM-DD): "); + LocalDate zahlungsziel = LocalDate.parse(scanner.nextLine()); + belegService.erstelleRechnungAusAngebot(angebotsNr, rechnungsdatum, leistungsdatum, zahlungsziel); + } + + private static void alleRechnungenAnzeigen() { + System.out.println("\n--- ALLE RECHNUNGEN ---"); + List rechnungen = belegService.alleRechnungen(); + if (rechnungen.isEmpty()) { System.out.println("Keine Rechnungen vorhanden."); return; } + rechnungen.forEach(r -> System.out.println(r.getBelegnummer() + " | Kunde: " + + r.getKundenReferenz() + " | Status: " + r.getStatus() + + " | Festgeschrieben: " + r.isFestgeschrieben())); + } + + private static void rechnungFestschreiben() { + System.out.println("\n--- RECHNUNG FESTSCHREIBEN ---"); + System.out.print("Rechnungsnummer: "); + belegService.finalisiereRechnung(scanner.nextLine()); + } } \ No newline at end of file