187 lines
6.4 KiB
JavaScript
187 lines
6.4 KiB
JavaScript
/**
|
|
* 🌐 JS 13: ES MODULE & ARCHITEKTUR (CLEAN CODE & SEPARATION OF CONCERNS) 🌐
|
|
* =========================================================================
|
|
* In diesem Modul lernst du, wie modularer Code mit klarer Trennung von
|
|
* Geschäftslogik (Math), Präsentation (Formatter) und Controller (Engine)
|
|
* aufgebaut wird.
|
|
*/
|
|
|
|
// ============================================================================
|
|
// 1. MODUL: MathModule (Reine mathematische Geschäftslogik)
|
|
// ============================================================================
|
|
const MathModule = {
|
|
/**
|
|
* 🎯 TEILZIEL 1 (TODO 1a): addieren(a, b)
|
|
* Addiert zwei Zahlen. Wirft TypeError falls a oder b keine gültige Zahl ist.
|
|
* @param {number} a
|
|
* @param {number} b
|
|
* @returns {number}
|
|
*/
|
|
addieren(a, b) {
|
|
// TODO: Validierung & Addition
|
|
return 0;
|
|
},
|
|
|
|
/**
|
|
* 🎯 TEILZIEL 1 (TODO 1b): subtrahieren(a, b)
|
|
* Subtrahiert b von a. Wirft TypeError falls a oder b keine gültige Zahl ist.
|
|
* @param {number} a
|
|
* @param {number} b
|
|
* @returns {number}
|
|
*/
|
|
subtrahieren(a, b) {
|
|
// TODO: Validierung & Subtraktion
|
|
return 0;
|
|
},
|
|
|
|
/**
|
|
* 🎯 TEILZIEL 1 (TODO 1c): multiplizieren(a, b)
|
|
* Multipliziert zwei Zahlen. Wirft TypeError falls a oder b keine gültige Zahl ist.
|
|
* @param {number} a
|
|
* @param {number} b
|
|
* @returns {number}
|
|
*/
|
|
multiplizieren(a, b) {
|
|
// TODO: Validierung & Multiplikation
|
|
return 0;
|
|
},
|
|
|
|
/**
|
|
* 🎯 TEILZIEL 1 (TODO 1d): dividieren(a, b)
|
|
* Dividiert a durch b. Wirft TypeError bei ungültigen Zahlen und
|
|
* Error("Division durch 0 nicht erlaubt") falls b === 0 ist.
|
|
* @param {number} a
|
|
* @param {number} b
|
|
* @returns {number}
|
|
*/
|
|
dividieren(a, b) {
|
|
// TODO: Validierung, 0-Prüfung & Division
|
|
return 0;
|
|
},
|
|
|
|
/**
|
|
* 🎯 TEILZIEL 1 (TODO 1e): runden(betrag, dezimalstellen = 2)
|
|
* Rundet kaufmännisch auf die übergebene Anzahl von Nachkommastellen.
|
|
* @param {number} betrag
|
|
* @param {number} [dezimalstellen=2]
|
|
* @returns {number}
|
|
*/
|
|
runden(betrag, dezimalstellen = 2) {
|
|
// TODO: Kaufmännisches Runden
|
|
return 0;
|
|
}
|
|
};
|
|
|
|
// ============================================================================
|
|
// 2. MODUL: FormatterModule (Präsentations- & Formatierungslogik)
|
|
// ============================================================================
|
|
const FormatterModule = {
|
|
/**
|
|
* 🎯 TEILZIEL 2 (TODO 2a): formatiereWaehrung(betrag, waehrung = "EUR")
|
|
* Formatiert eine Zahl im deutschen Währungsformat mit 2 Nachkommastellen
|
|
* und Tausender-Trennzeichen:
|
|
* z.B. 1250.5 -> "1.250,50 EUR", 49.99 -> "49,99 EUR", 0 -> "0,00 EUR"
|
|
* Wirft TypeError falls betrag keine Zahl ist oder waehrung ungültig ist.
|
|
*
|
|
* @param {number} betrag
|
|
* @param {string} [waehrung="EUR"]
|
|
* @returns {string}
|
|
*/
|
|
formatiereWaehrung(betrag, waehrung = "EUR") {
|
|
// TODO: Betrag runden, deutsches Format mit Komma und Tausender-Punkt erstellen
|
|
return "";
|
|
},
|
|
|
|
/**
|
|
* 🎯 TEILZIEL 2 (TODO 2b): formatiereDatumIso(datum)
|
|
* Wandelt ein Date-Objekt oder einen Datums-String in das ISO-Format "YYYY-MM-DD" um.
|
|
* Wirft TypeError falls das Datum ungültig ist.
|
|
* z.B. new Date(2026, 7, 30) -> "2026-08-30"
|
|
*
|
|
* @param {Date | string | number} datum
|
|
* @returns {string}
|
|
*/
|
|
formatiereDatumIso(datum) {
|
|
// TODO: Date-Objekt validieren und als YYYY-MM-DD formatieren
|
|
return "";
|
|
}
|
|
};
|
|
|
|
// ============================================================================
|
|
// 3. HAUPT-CONTROLLER: RechnungsEngine (Orchestrator mit Dependency Injection)
|
|
// ============================================================================
|
|
/**
|
|
* @typedef {Object} Rechnungsposition
|
|
* @property {string} bezeichnung - Name des Artikels / der Dienstleistung
|
|
* @property {number} menge - Anzahl (muss > 0 sein)
|
|
* @property {number} einzelpreis - Preis pro Einheit (muss >= 0 sein)
|
|
* @property {number} gesamtpreis - menge * einzelpreis
|
|
*/
|
|
|
|
/**
|
|
* @typedef {Object} Rechnung
|
|
* @property {Rechnungsposition[]} positionen
|
|
* @property {number} nettoSumme
|
|
* @property {number} steuersatzProzent
|
|
* @property {number} steuerBetrag
|
|
* @property {number} bruttoSumme
|
|
* @property {string} nettoFormatiert
|
|
* @property {string} steuerFormatiert
|
|
* @property {string} bruttoFormatiert
|
|
*/
|
|
|
|
class RechnungsEngine {
|
|
/**
|
|
* Konstruktor mit Dependency Injection:
|
|
* Erlaubt das Austauschen der Module für Tests oder andere Währungen/Formate.
|
|
* @param {typeof MathModule} [mathMod=MathModule]
|
|
* @param {typeof FormatterModule} [formatMod=FormatterModule]
|
|
*/
|
|
constructor(mathMod = MathModule, formatMod = FormatterModule) {
|
|
this.math = mathMod;
|
|
this.formatter = formatMod;
|
|
}
|
|
|
|
/**
|
|
* 🎯 TEILZIEL 3 (TODO 3): erstellePosition(bezeichnung, menge, einzelpreis)
|
|
* Erstellt eine validierte Rechnungsposition und berechnet den gesamtpreis.
|
|
*
|
|
* Anforderungen:
|
|
* - bezeichnung: string (nach .trim() nicht leer, sonst Error werfen)
|
|
* - menge: number (> 0, sonst RangeError)
|
|
* - einzelpreis: number (>= 0, sonst RangeError)
|
|
* - gesamtpreis berechnen über this.math.multiplizieren(menge, einzelpreis)
|
|
* - Rückgabe: { bezeichnung, menge, einzelpreis, gesamtpreis }
|
|
*
|
|
* @param {string} bezeichnung
|
|
* @param {number} menge
|
|
* @param {number} einzelpreis
|
|
* @returns {Rechnungsposition}
|
|
*/
|
|
erstellePosition(bezeichnung, menge, einzelpreis) {
|
|
// TODO: Validierung & Erstellung der Position
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* 🎯 TEILZIEL 4 (TODO 4): berechneRechnung(positionen, steuersatzProzent = 19)
|
|
* Berechnet Gesamtsummen, Steuern und formatierte Ausgaben für eine Liste von Positionen.
|
|
*
|
|
* Anforderungen:
|
|
* - positionen: Array von Rechnungspositionen (falls leer, Summen = 0)
|
|
* - steuersatzProzent: number (Standard: 19)
|
|
* - nettoSumme: Summe aller p.gesamtpreis (mit this.math.addieren berechnen)
|
|
* - steuerBetrag: this.math.runden(this.math.multiplizieren(nettoSumme, steuersatzProzent / 100), 2)
|
|
* - bruttoSumme: this.math.addieren(nettoSumme, steuerBetrag)
|
|
* - Formatierte Werte über this.formatter.formatiereWaehrung() erzeugen
|
|
* - Rückgabe: Das fertige Rechnung-Objekt
|
|
*
|
|
* @param {Rechnungsposition[]} positionen
|
|
* @param {number} [steuersatzProzent=19]
|
|
* @returns {Rechnung}
|
|
*/
|
|
berechneRechnung(positionen, steuersatzProzent = 19) {
|
|
// TODO: Netto, Steuer, Brutto und formatierte Werte berechnen
|
|
return null;
|
|
}
|
|
}
|