diff --git a/Dienstplan_Portable.html b/Dienstplan_Portable.html index 5fa79f0..af9cbb1 100644 --- a/Dienstplan_Portable.html +++ b/Dienstplan_Portable.html @@ -448,7 +448,7 @@

Monatsauswertung

Berechnungsregeln (Variante 2 - Streng)

Schwelle: Gesamter Bonus wird nur gezahlt, wenn WE-Einheiten ≥ 2,0.
- Bei Erreichen: WT = 250 EUR/Einheit, WE = 450 EUR/Einheit (abzgl. 1,0 Einheit Abzug).
+ Bei Erreichen: WT = 250 EUR/Einheit, WE = 450 EUR/Einheit (abzgl. 2,0 Einheiten Abzug).
Unter Schwelle: Keine Auszahlung (weder WT noch WE).
WE-Tage: Fr, Sa, So, Feiertage und Vortage von Feiertagen.

@@ -576,7 +576,7 @@

Gefahrenzone

RATE_WT: 250, RATE_WE: 450, THRESHOLD: 2.0, - DEDUCTION: 1.0, + DEDUCTION: 2.0, TOLERANCE: 0.0001 }; @@ -1071,7 +1071,7 @@

Gefahrenzone

csv += 'WT;Werktag (Montag-Donnerstag ohne Feiertag/Vortag)\n'; csv += 'WE-Tag;"Freitag, Samstag, Sonntag, Feiertag oder Tag vor Feiertag"\n'; csv += 'Schwelle;"Mindestens 2,0 WE-Einheiten für Bonuszahlung erforderlich"\n'; - csv += 'Sätze;"WT = 250 EUR/Einheit, WE = 450 EUR/Einheit (abzgl. 1,0 Abzug)"\n'; + csv += 'Sätze;"WT = 250 EUR/Einheit, WE = 450 EUR/Einheit (abzgl. 2,0 Abzug)"\n'; // Download CSV file const blob = new Blob([csv], { type: 'text/csv;charset=utf-8' }); @@ -1296,20 +1296,23 @@
Monat ${MONTHS[m]} ${y} mit Auszahlung Ende ${MONTHS[payoutMonth]} ${payoutY totalBonus += bonus; - // Generate note for this employee + // Generate note for this employee - cleaner, more professional format const safeName = this.sanitizeName(name); - let note = `${safeName}: `; + let note = ''; if (!thresholdReached) { - note += `Erreicht das Bonussystem nicht (nur ${we_total.toFixed(1)} WE-Einheiten, mind. 2,0 erforderlich).`; + note = `${safeName} erreicht die Mindestschwelle nicht (${we_total.toFixed(1)} von ${CONFIG.THRESHOLD.toFixed(1)} WE-Einheiten) und erhält daher keine Bonuszahlung.`; } else { - const details = []; - if (data.wt > 0) details.push(`${data.wt.toFixed(1)} WT × 250€`); - if (data.we_fr > 0 || data.we_other > 0) { - const paid_we = we_total - 1.0; - details.push(`${paid_we.toFixed(1)} WE × 450€ (abzgl. 1,0 Abzug von ${deductedFrom})`); + const paid_we = we_total - CONFIG.DEDUCTION; + let breakdown = []; + if (data.wt > 0) breakdown.push(`${data.wt.toFixed(1)} WT-Einheiten à ${CONFIG.RATE_WT} €`); + if (paid_we > 0) breakdown.push(`${paid_we.toFixed(1)} WE-Einheiten à ${CONFIG.RATE_WE} €`); + + note = `${safeName} erhält eine Bonuszahlung von ${this.formatCurrency(bonus)}`; + if (breakdown.length > 0) { + note += ` (${breakdown.join(' + ')})`; } - note += `Erhält ${this.formatCurrency(bonus)}. ${details.join(', ')}.`; + note += '.'; } employeeNotes.push(note); @@ -1370,7 +1373,7 @@

Erläuterungen zu den einzelnen Mitarbeitern:

  • Vergütung bei Erreichen der Schwelle:
  • Unter Schwelle: Keine Bonuszahlung (weder WT noch WE)
  • diff --git a/README.md b/README.md index 69e94b4..4e0e728 100644 --- a/README.md +++ b/README.md @@ -103,7 +103,7 @@ Die Datei landet in `output/Dienstplan_YYYY_MM_NRW.xlsx`. - **WE-Tag**: Fr/Sa/So + Feiertag + Vortag Feiertag - **WT-Tag**: Alle anderen Tage (250 € pro Einheit) -- **WE-Vergütung**: Nur wenn Monatssumme ≥ 2,0 WE-Einheiten → 450 €/Einheit, dann Abzug 1,0 (zuerst von Freitag) +- **WE-Vergütung**: Nur wenn Monatssumme ≥ 2,0 WE-Einheiten → 450 €/Einheit, dann Abzug 2,0 (zuerst von Freitag) - **Unter Schwelle**: WE-Dienste = 0 € (nicht als WT vergütet) Details siehe `SPECIFICATION.md`. diff --git a/SPECIFICATION.md b/SPECIFICATION.md index 6021df3..b0a7d7c 100644 --- a/SPECIFICATION.md +++ b/SPECIFICATION.md @@ -4,7 +4,7 @@ Stand: 14.11.2025 (Deutschland) ## Ziel -Diese README beschreibt vollständig, wie eine Excel-Arbeitsmappe aufgebaut wird, die Monatsdienste erfasst und automatisch die Vergütung ermittelt – inkl. Erkennung von Wochenend-/Feiertagsdiensten (inkl. Vortag), Schwellenlogik und Abzug 1,0 WE-Einheit. Variante 2 (streng) ist aktiv: WE-Dienste werden nur vergütet, wenn im Monat mindestens 2,0 WE-Einheiten erreicht werden; sonst 0 €. Wochentage (kein WE) werden stets vergütet. +Diese README beschreibt vollständig, wie eine Excel-Arbeitsmappe aufgebaut wird, die Monatsdienste erfasst und automatisch die Vergütung ermittelt – inkl. Erkennung von Wochenend-/Feiertagsdiensten (inkl. Vortag), Schwellenlogik und Abzug 2,0 WE-Einheiten nach Erreichen der Schwelle. Variante 2 (streng) ist aktiv: WE-Dienste werden nur vergütet, wenn im Monat mindestens 2,0 WE-Einheiten erreicht werden; sonst 0 €. Wochentage (kein WE) werden ebenfalls nur bei Erreichen der WE-Schwelle vergütet. Hinweise: - Region: Deutschland, Bundesland wählbar (steuert Feiertage). @@ -279,17 +279,17 @@ Beispiel-Formel (als hilfsweise Matrix in Checks): A hat 1,75 WE und 1,0 WT → Auszahlung_WE = 0 €; Auszahlung_WT = 0 €; Auszahlung_Gesamt = 0 €. 2) **Genau Schwelle**: - A hat 2,0 WE (Fr 1,0 + Sa 1,0) → Abzug 1,0 (zuerst Fr) → WE_bezahlt = 1,0 → 450 €. + A hat 2,0 WE (Fr 1,0 + Sa 1,0) → Abzug 2,0 (zuerst Fr) → WE_bezahlt = 0,0 → 0 €. 3) **Über Schwelle ohne Freitag**: - A hat 2,0 WE (nur Sa+So) → Abzug 1,0 aus „Andere" → WE_bezahlt = 1,0 → 450 €. + A hat 2,0 WE (nur Sa+So) → Abzug 2,0 aus „Andere" → WE_bezahlt = 0,0 → 0 €. 4) **Starke Überdeckung**: - A hat 3,5 WE → Abzug 1,0 → WE_bezahlt = 2,5 → 2,5×450 €. + A hat 3,5 WE → Abzug 2,0 → WE_bezahlt = 1,5 → 1,5×450 € = 675 €. 5) **Splits rund um 2,0**: - A hat Fr 0,4 + Sa 0,6 + So 1,0 → Summe 2,0 → Abzug 1,0 - (0,4 von Fr, 0,6 von Andere) → WE_bezahlt = 1,0 → 450 €. + A hat Fr 0,4 + Sa 0,6 + So 1,0 → Summe 2,0 → Abzug 2,0 + (0,4 von Fr, 1,6 von Andere) → WE_bezahlt = 0,0 → 0 €. 6) **Unter Schwelle, nur WE-Tage**: A hat 1,0 WE, 0 WT → Auszahlung_WE = 0 €; Auszahlung_Gesamt = 0 €. @@ -300,9 +300,9 @@ Beispiel-Formel (als hilfsweise Matrix in Checks): ## Edge-Cases und Präzisierungen -- Abzug nur einmal pro Person/Monat (fix 1,0), und nur wenn Schwelle erreicht. +- Abzug nur einmal pro Person/Monat (fix 2,0), und nur wenn Schwelle erreicht. - Der Vortag eines Feiertags ist WE-Tag – unabhängig davon, welcher Wochentag er ist. -- Wenn WE_Freitag < 1,0, wird der restliche Abzug (bis 1,0) von WE_Andere genommen. +- Wenn WE_Freitag < 2,0, wird der restliche Abzug (bis 2,0) von WE_Andere genommen. - Monatswechsel: Daten genau per >=Monat_Auswahl und <=EOMONAT(Monat_Auswahl;0) filtern. - Rundungstoleranz 1e-4 bei Schwelle und Datumssummen (Splits wie 0,33/0,67). - Tabellen-Namen („tblPlan", „tblFeiertage", „tblAuswertung") konsequent verwenden. @@ -324,11 +324,11 @@ Lieferumfang (empfohlen): - 18.11.2025: Korrektur Variante 2: **Gesamter Bonus (WT + WE) wird nur gezahlt, wenn WE_Summe ≥ 2,0**. Unter Schwelle: Auszahlung_Gesamt = 0 € (weder WT noch WE). - 14.11.2025: Umstellung auf Variante 2 (streng). WE-Vergütung nur bei WE_Summe ≥ 2,0, - anschließend Abzug 1,0 (Freitag zuerst). Unterhalb der Schwelle: WE-Auszahlung = 0 €. + anschließend Abzug 2,0 (Freitag zuerst). Unterhalb der Schwelle: WE-Auszahlung = 0 €. - 13.11.2025: Vorversion (Variante 1) mit WE-Auszahlung ab erstem WE-Dienst und Abzug nach Schwelle (ersetzt). ## Kurztext (für Blatt „Regeln" als Readme-Hinweis) -„WE-Tag = Fr/Sa/So/Feiertag/Vortag (BL-abhängig). Variante 2 (streng): Gesamter Bonus (WT + WE) wird nur gezahlt, wenn im Monat ≥ 2,0 WE-Einheiten erreicht werden. Bei Erreichen der Schwelle: WT 250 €/Einheit, WE 450 €/Einheit mit Abzug 1,0 (Freitag zuerst). Unter Schwelle: 0 € Auszahlung. Splits anteilig. Monat und Bundesland oben wählen." +„WE-Tag = Fr/Sa/So/Feiertag/Vortag (BL-abhängig). Variante 2 (streng): Gesamter Bonus (WT + WE) wird nur gezahlt, wenn im Monat ≥ 2,0 WE-Einheiten erreicht werden. Bei Erreichen der Schwelle: WT 250 €/Einheit, WE 450 €/Einheit mit Abzug 2,0 (Freitag zuerst). Unter Schwelle: 0 € Auszahlung. Splits anteilig. Monat und Bundesland oben wählen." — Ende der README — diff --git a/android-app/IMPLEMENTATION_SUMMARY.md b/android-app/IMPLEMENTATION_SUMMARY.md index 55e510f..392424c 100644 --- a/android-app/IMPLEMENTATION_SUMMARY.md +++ b/android-app/IMPLEMENTATION_SUMMARY.md @@ -78,8 +78,8 @@ Implements NRW Variante 2 (streng) rules: #### Unit Tests (PayrollCalculatorTest.kt) Comprehensive test coverage including: 1. **Under threshold test**: 1.75 WE + 1.0 WT → WE payout 0€, WT payout 250€ -2. **Exactly at threshold test**: 2.0 WE → WE payout 450€ (1.0 unit after deduction) -3. **Over threshold test**: 3.5 WE → WE payout 1125€ (2.5 units after deduction) +2. **Exactly at threshold test**: 2.0 WE → WE payout 0€ (0.0 units after 2.0 deduction) +3. **Over threshold test**: 3.5 WE → WE payout 675€ (1.5 units after 2.0 deduction) 4. **Friday deduction priority test**: Verifies deduction comes from Friday first 5. **Multiple employees test**: Separate calculations per employee diff --git a/android-app/app/src/main/java/com/dienstplan/nrw/data/PayrollCalculator.kt b/android-app/app/src/main/java/com/dienstplan/nrw/data/PayrollCalculator.kt index 5d8f932..25ebe44 100644 --- a/android-app/app/src/main/java/com/dienstplan/nrw/data/PayrollCalculator.kt +++ b/android-app/app/src/main/java/com/dienstplan/nrw/data/PayrollCalculator.kt @@ -12,11 +12,11 @@ import kotlin.math.min * Business rules: * - WE-Tag (Weekend/Holiday): Friday, Saturday, Sunday, public holiday, day before public holiday * - WT-Tag (Weekday): All other days - * - WT compensation: Always 250€ per unit + * - WT compensation: 250€ per unit (only if threshold reached) * - WE compensation: Only paid if monthly total >= 2.0 WE units (threshold) * - If threshold reached: 450€ per WE unit, then deduct exactly 2.0 WE units * - Deduction priority: Friday first, then other WE days - * - Below threshold: 0€ for WE shifts (NOT converted to WT) + * - Below threshold: 0€ for all shifts (neither WT nor WE) */ class PayrollCalculator { diff --git a/android-app/app/src/test/java/com/dienstplan/nrw/PayrollCalculatorTest.kt b/android-app/app/src/test/java/com/dienstplan/nrw/PayrollCalculatorTest.kt index dbabf20..6a03b0a 100644 --- a/android-app/app/src/test/java/com/dienstplan/nrw/PayrollCalculatorTest.kt +++ b/android-app/app/src/test/java/com/dienstplan/nrw/PayrollCalculatorTest.kt @@ -52,7 +52,7 @@ class PayrollCalculatorTest { /** * Test Case 2: Exactly at threshold (2.0 WE) - * Expected: WE payout = 0€ (0.0 units after deduction), threshold reached + * Expected: WE payout = 0€ (0.0 units after 2.0 deduction), threshold reached */ @Test fun testExactlyAtThreshold() { @@ -74,7 +74,7 @@ class PayrollCalculatorTest { /** * Test Case 3: Over threshold (3.5 WE) - * Expected: WE payout = 675€ (1.5 units after deduction) + * Expected: WE payout = 675€ (1.5 units after 2.0 deduction) */ @Test fun testOverThreshold() { @@ -117,6 +117,7 @@ class PayrollCalculatorTest { assertEquals(0.4, result.deductionFriday, 0.001) // All Friday deducted first assertEquals(1.6, result.deductionOther, 0.001) // Rest from other (1.6 to reach 2.0 total) assertEquals(0.0, result.wePaid, 0.001) + assertEquals(0.0, result.payoutWE, 0.001) } /** @@ -144,7 +145,7 @@ class PayrollCalculatorTest { assertFalse(resultA.thresholdReached) assertEquals(0.0, resultA.payoutWE, 0.001) - // B: above threshold + // B: above threshold (2.5 WE - 2.0 deduction = 0.5 paid) assertTrue(resultB.thresholdReached) assertEquals(2.5, resultB.weTotal, 0.001) assertEquals(0.5, resultB.wePaid, 0.001) diff --git a/claude.md b/claude.md index 9fde052..0d18bd2 100644 --- a/claude.md +++ b/claude.md @@ -53,11 +53,11 @@ Die ältere Implementierung nutzt eine andere Logik: - **WE-Tag** (Weekend): Fr-So + Feiertag + Vortag Feiertag 2. **Bonusberechnung**: - - **WT-Tage** werden **immer** mit 250€ vergütet + - **WT-Tage** werden bei Erreichen der Schwelle mit 250€ vergütet - **WE-Tage** nur vergütet wenn ≥ 2.0 WE-Einheiten: - Bei Erreichen: 450€ pro WE-Tag - Dann Abzug von 2.0 WE-Einheiten (Freitag-Priorität) - - Unter Schwellenwert: WE-Dienste = 0€ (nicht als WT vergütet) + - Unter Schwellenwert: Keine Bonuszahlung (weder WE noch WT) ### Wichtiger Unterschied - Beispiel @@ -203,18 +203,13 @@ this.RATE_WEEKEND = 500; // Statt 450 ``` ### Abzug ändern (Web-App) -Aktuell ist der Abzug fest auf 2.0 kodiert in `webapp/calculator.js`, Zeile 112: -```javascript -qualifyingDaysDeducted = 2.0; -``` - -Um dies flexibel zu machen, könnte man hinzufügen: +Der Abzug ist als Konstante in `webapp/calculator.js` definiert: ```javascript this.DEDUCTION_AMOUNT = 2.0; // Im Constructor -// Dann verwenden: -qualifyingDaysDeducted = this.DEDUCTION_AMOUNT; ``` +Um den Abzugswert zu ändern, einfach diesen Wert anpassen. + ## Code-Architektur ### Web-App (MVC-ähnlich) diff --git a/src/build_template.py b/src/build_template.py index 7a6d1b5..f9f3cfd 100644 --- a/src/build_template.py +++ b/src/build_template.py @@ -61,7 +61,7 @@ def _populate_readme(ws): rules = [ "WE-Tag = Fr/Sa/So/Feiertag/Vortag (BL-abhängig).", "Variante 2 (streng): WE werden nur vergütet, wenn im Monat ≥ 2,0 WE-Einheiten erreicht werden;", - "dann 450 €/WE und Abzug 2,0 (Freitag zuerst). WT werden immer mit 250 € vergütet.", + "dann 450 €/WE und Abzug 2,0 (Freitag zuerst). WT werden bei Erreichen der WE-Schwelle mit 250 € vergütet.", "Splits anteilig. Monat und Bundesland in 'Regeln' wählen.", "", "Schritte:", diff --git a/webapp/README.md b/webapp/README.md index 12e74a0..00da5ad 100644 --- a/webapp/README.md +++ b/webapp/README.md @@ -21,7 +21,7 @@ Eine Web-Anwendung zur Berechnung von Bonuszahlungen für Wochenend- und Feierta ### Bonusberechnung 1. **Schwellenwert**: Mindestens **2.0 qualifizierende Tage** im Monat erforderlich -2. **Abzug**: Bei Erreichen des Schwellenwerts werden **2.0 qualifizierende Tage** abgezogen +2. **Abzug**: Bei Erreichen des Schwellenwerts werden **2.0 qualifizierende Tage** abgezogen (Freitag-Priorität) 3. **Vergütung**: - Normale Tage: **250€** pro Tag - Qualifizierende Tage (WE/Feiertag): **450€** pro Tag diff --git a/webapp/TEST_GUIDE.md b/webapp/TEST_GUIDE.md index b8e29f0..6a43fbf 100644 --- a/webapp/TEST_GUIDE.md +++ b/webapp/TEST_GUIDE.md @@ -110,8 +110,8 @@ Dienste: Erwartung: - Normale Tage: 0.5 × 250€ = 125€ -- Qualifizierende Tage: (2.5 - 1.0) × 450€ = 675€ -- Gesamt: 800€ +- Qualifizierende Tage: (2.5 - 2.0) × 450€ = 225€ +- Gesamt: 350€ ``` ## Tests erweitern diff --git a/webapp/app.js b/webapp/app.js index 45a3519..0b5193a 100644 --- a/webapp/app.js +++ b/webapp/app.js @@ -526,7 +526,7 @@ class DienstplanApp { csv += 'WE/Feiertag Tage;"Freitag, Samstag, Sonntag, Feiertag oder Tag vor Feiertag"\n'; csv += 'Schwelle;"Mindestens 2,0 WE-Einheiten für Bonuszahlung erforderlich"\n'; csv += 'Sätze;"Normale Tage = 250 EUR/Einheit, WE/Feiertag = 450 EUR/Einheit"\n'; - csv += 'Abzug;"Bei Erreichen der Schwelle wird 1,0 WE-Einheit abgezogen"\n'; + csv += 'Abzug;"Bei Erreichen der Schwelle werden 2,0 WE-Einheiten abgezogen"\n'; // Download CSV file const blob = new Blob([csv], { type: 'text/csv;charset=utf-8' }); @@ -738,7 +738,7 @@ class DienstplanApp { if (thresholdReached) { const wt_pay = data.wt * this.calculator.RATE_NORMAL; - let deduct = 1.0; + let deduct = this.calculator.DEDUCTION_AMOUNT; const deduct_fr = Math.min(deduct, data.we_fr); const deduct_other = Math.max(0, deduct - deduct_fr); const paid_fr = Math.max(0, data.we_fr - deduct_fr); @@ -757,20 +757,23 @@ class DienstplanApp { totalBonus += bonus; - // Generate note + // Generate note - cleaner, more professional format const safeName = escapeHtml(name); - let note = `${safeName}: `; + let note = ''; if (!thresholdReached) { - note += `Erreicht das Bonussystem nicht (nur ${we_total.toFixed(1)} WE-Einheiten, mind. 2,0 erforderlich).`; + note = `${safeName} erreicht die Mindestschwelle nicht (${we_total.toFixed(1)} von ${this.calculator.MIN_QUALIFYING_DAYS.toFixed(1)} WE-Einheiten) und erhält daher keine Bonuszahlung.`; } else { - const details = []; - if (data.wt > 0) details.push(`${data.wt.toFixed(1)} WT × 250€`); - if (data.we_fr > 0 || data.we_other > 0) { - const paid_we = we_total - 1.0; - details.push(`${paid_we.toFixed(1)} WE × 450€ (abzgl. 1,0 Abzug von ${deductedFrom})`); + const paid_we = we_total - this.calculator.DEDUCTION_AMOUNT; + let breakdown = []; + if (data.wt > 0) breakdown.push(`${data.wt.toFixed(1)} WT-Einheiten à ${this.calculator.RATE_NORMAL} €`); + if (paid_we > 0) breakdown.push(`${paid_we.toFixed(1)} WE-Einheiten à ${this.calculator.RATE_WEEKEND} €`); + + note = `${safeName} erhält eine Bonuszahlung von ${this.calculator.formatCurrency(bonus)}`; + if (breakdown.length > 0) { + note += ` (${breakdown.join(' + ')})`; } - note += `Erhält ${this.calculator.formatCurrency(bonus)}. ${details.join(', ')}.`; + note += '.'; } employeeNotes.push(note); @@ -832,7 +835,7 @@ class DienstplanApp {
  • Vergütung bei Erreichen der Schwelle:
  • Unter Schwelle: Keine Bonuszahlung (weder WT noch WE)
  • diff --git a/webapp/calculator.js b/webapp/calculator.js index d705419..a3edb2e 100644 --- a/webapp/calculator.js +++ b/webapp/calculator.js @@ -8,6 +8,7 @@ class BonusCalculator { this.RATE_NORMAL = 250; // Normal day rate (not weekend/holiday) this.RATE_WEEKEND = 450; // Weekend/holiday rate this.MIN_QUALIFYING_DAYS = 2.0; // Minimum qualifying days to trigger bonus + this.DEDUCTION_AMOUNT = 2.0; // Deduction after reaching threshold } /** @@ -108,8 +109,8 @@ class BonusCalculator { let totalDeduction = 0; if (thresholdReached) { - // Deduct 2.0 qualifying days with Friday priority - totalDeduction = 2.0; + // Deduct qualifying days with Friday priority + totalDeduction = this.DEDUCTION_AMOUNT; // First deduct from Friday deductionFromFriday = Math.min(totalDeduction, qualifyingDaysFriday); diff --git a/webapp/test-suite.js b/webapp/test-suite.js index 03e85a9..420306e 100644 --- a/webapp/test-suite.js +++ b/webapp/test-suite.js @@ -191,7 +191,7 @@ runner.test('Berechnung: Unter Schwellenwert (1.0 WE-Tag) = 0€', (t) => { t.assertEqual(result.totalBonus, 0, 'Bonus sollte 0€ sein'); }); -runner.test('Berechnung: Genau 2.0 WE-Tage = 450€', (t) => { +runner.test('Berechnung: Genau 2.0 WE-Tage = 0€', (t) => { const holidays = new HolidayProvider(); const calculator = new BonusCalculator(holidays); @@ -209,7 +209,7 @@ runner.test('Berechnung: Genau 2.0 WE-Tage = 450€', (t) => { t.assertEqual(result.totalBonus, 0, 'Bonus sollte 0€ sein'); }); -runner.test('Berechnung: 2x halbe WE-Dienste = 0€ (genau Schwelle, aber nach Abzug nichts)', (t) => { +runner.test('Berechnung: 2x halbe WE-Dienste = 0€ (genau Schwelle, nach Abzug 2.0)', (t) => { const holidays = new HolidayProvider(); const calculator = new BonusCalculator(holidays); @@ -241,7 +241,7 @@ runner.test('Berechnung: 3 WE-Tage = 450€', (t) => { const result = calculator.calculateMonthlyBonus(duties); t.assertEqual(result.qualifyingDays, 3.0, 'Sollte 3.0 qualifizierende Tage haben'); - t.assertEqual(result.qualifyingDaysPaid, 1.0, 'Sollte 1.0 Tag bezahlen (3-2)'); + t.assertEqual(result.qualifyingDaysPaid, 1.0, 'Sollte 1.0 Tage bezahlen (3-2)'); t.assertEqual(result.totalBonus, 450, 'Bonus sollte 450€ sein (1×450€)'); }); @@ -261,7 +261,7 @@ runner.test('Berechnung: Normale Tage + WE-Tage gemischt', (t) => { t.assertEqual(result.normalDays, 2.0, 'Sollte 2.0 normale Tage haben'); t.assertEqual(result.qualifyingDays, 2.0, 'Sollte 2.0 qualifizierende Tage haben'); t.assertEqual(result.normalDaysPaid, 2.0, 'Sollte 2.0 normale Tage bezahlen'); - t.assertEqual(result.qualifyingDaysPaid, 0.0, 'Sollte 0.0 qualifizierenden Tag bezahlen'); + t.assertEqual(result.qualifyingDaysPaid, 0.0, 'Sollte 0.0 qualifizierende Tage bezahlen'); t.assertEqual(result.bonusNormalDays, 500, 'Normale Tage: 2×250€ = 500€'); t.assertEqual(result.bonusQualifyingDays, 0, 'WE-Tage: 0×450€ = 0€'); t.assertEqual(result.totalBonus, 500, 'Gesamt: 500€'); @@ -301,7 +301,7 @@ runner.test('Berechnung: Feiertag + Vortag', (t) => { t.assertEqual(result.qualifyingDays, 2.0, 'Sollte 2.0 qualifizierende Tage haben'); t.assertTrue(result.thresholdReached, 'Schwellenwert sollte erreicht sein'); - t.assertEqual(result.totalBonus, 0, 'Bonus sollte 0€ sein'); + t.assertEqual(result.totalBonus, 0, 'Bonus sollte 0€ sein (2.0 - 2.0 = 0.0 × 450€)'); }); runner.test('Berechnung: Keine Dienste = 0€', (t) => {