diff --git a/test-suite.js b/test-suite.js index ba43229..b31834f 100644 --- a/test-suite.js +++ b/test-suite.js @@ -734,6 +734,65 @@ runner.test('variant1: threshold-Shape normal {frSo:1, weekday:3}', (t) => { t.assertEqual(r.threshold.weekday, 3, 'threshold.weekday=3'); }); +// ============================================================================ +// Variants - variant2 (1 sa + 2 weekday) +// ============================================================================ + +runner.test('variant2: Schwelle nicht erreicht (sa=0)', (t) => { + const r = variant2({ fr: 5, sa: 0, so: 5, weekday: 3 }, false); + t.assertFalse(r.eligible, 'eligible=false'); + t.assertEqual(r.bonus, 0, 'bonus=0'); +}); + +runner.test('variant2: Schwelle nicht erreicht (weekday<2)', (t) => { + const r = variant2({ fr: 0, sa: 2, so: 0, weekday: 1 }, false); + t.assertFalse(r.eligible, 'eligible=false'); +}); + +runner.test('variant2: Spec-Beispiel fr=1,sa=2,so=0,weekday=3 -> 1150', (t) => { + const r = variant2({ fr: 1, sa: 2, so: 0, weekday: 3 }, false); + t.assertTrue(r.eligible, 'eligible=true'); + t.assertEqual(r.deduction.sa, 1, 'sa-deduction=1'); + t.assertEqual(r.deduction.weekday, 2, 'weekday-deduction=2'); + t.assertEqual(r.deduction.fr, 0, 'fr nicht abgezogen'); + t.assertEqual(r.deduction.so, 0, 'so nicht abgezogen'); + t.assertEqual(r.paidShares.fr, 1, 'fr-paid=1'); + t.assertEqual(r.paidShares.sa, 1, 'sa-paid=1'); + t.assertEqual(r.paidShares.weekday, 1, 'weekday-paid=1'); + t.assertEqual(r.bonus, 1150, 'bonus = (1+1+0)*450 + 1*250 = 1150'); +}); + +runner.test('variant2: sa=1,weekday=2 -> alles weg, bonus 0', (t) => { + const r = variant2({ fr: 0, sa: 1, so: 0, weekday: 2 }, false); + t.assertTrue(r.eligible, 'eligible=true'); + t.assertEqual(r.bonus, 0, 'bonus=0'); +}); + +runner.test('variant2: sa=2,weekday=2,fr=1,so=1 -> fr/so voll bezahlt', (t) => { + const r = variant2({ fr: 1, sa: 2, so: 1, weekday: 2 }, false); + t.assertEqual(r.paidShares.fr, 1, 'fr-paid=1'); + t.assertEqual(r.paidShares.sa, 1, 'sa-paid=1'); + t.assertEqual(r.paidShares.so, 1, 'so-paid=1'); + t.assertEqual(r.paidShares.weekday, 0, 'weekday-paid=0'); + t.assertEqual(r.bonus, 3 * 450, 'bonus = 3*450 = 1350'); +}); + +runner.test('variant2: Urlaubsmodus halbiert (0.5 sa + 1 weekday)', (t) => { + const r = variant2({ fr: 0, sa: 0.5, so: 0, weekday: 1 }, true); + t.assertTrue(r.eligible, 'eligible=true im Urlaub'); + t.assertEqual(r.threshold.sa, 0.5, 'threshold.sa=0.5'); + t.assertEqual(r.threshold.weekday, 1, 'threshold.weekday=1'); + t.assertEqual(r.deduction.sa, 0.5, 'sa-deduction=0.5'); + t.assertEqual(r.deduction.weekday, 1, 'weekday-deduction=1'); + t.assertEqual(r.bonus, 0, 'bonus=0'); +}); + +runner.test('variant2: threshold-Shape normal {sa:1, weekday:2}', (t) => { + const r = variant2({ fr: 0, sa: 1, so: 0, weekday: 2 }, false); + t.assertEqual(r.threshold.sa, 1, 'threshold.sa=1'); + t.assertEqual(r.threshold.weekday, 2, 'threshold.weekday=2'); +}); + // ============================================================================ // Display Functions // ============================================================================ diff --git a/variants.js b/variants.js index 82ea181..60b0db1 100644 --- a/variants.js +++ b/variants.js @@ -89,7 +89,49 @@ function variant1(classified, isVacation) { } function variant2(classified, isVacation) { - throw new Error('variant2: not implemented'); + const RATE_NORMAL = 250; + const RATE_WEEKEND = 450; + const saThreshold = isVacation ? 0.5 : 1; + const weekdayThreshold = isVacation ? 1 : 2; + const saDeduction = isVacation ? 0.5 : 1; + const weekdayDeduction = isVacation ? 1 : 2; + + const eligible = (classified.sa >= saThreshold - 1e-9) + && (classified.weekday >= weekdayThreshold - 1e-9); + + if (!eligible) { + return { + variantId: 2, + eligible: false, + threshold: { sa: saThreshold, weekday: weekdayThreshold }, + deduction: { fr: 0, sa: 0, so: 0, weekday: 0 }, + paidShares: { fr: 0, sa: 0, so: 0, weekday: 0 }, + bonus: 0, + isWinner: false + }; + } + + const deduction = { fr: 0, sa: saDeduction, so: 0, weekday: weekdayDeduction }; + + const paidShares = { + fr: classified.fr, // fr never deducted in V2 + sa: Math.max(0, classified.sa - deduction.sa), + so: classified.so, // so never deducted in V2 + weekday: Math.max(0, classified.weekday - deduction.weekday) + }; + + const bonus = (paidShares.fr + paidShares.sa + paidShares.so) * RATE_WEEKEND + + paidShares.weekday * RATE_NORMAL; + + return { + variantId: 2, + eligible: true, + threshold: { sa: saThreshold, weekday: weekdayThreshold }, + deduction, + paidShares, + bonus, + isWinner: false + }; } function variant3(classified, isVacation) {