feat: agent-11 PR2 – Urlaubsanspruch (Verfall scharf, Pro-rata, Teilzeit)
Korrektheit der Urlaubskonten (Feature-Parität mit Urlaubsverwaltung):
- Verfall scharfgeschaltet: neuer effektiv verfügbarer Saldo (available_days)
schließt verfallenen, noch nicht verbrauchten Resturlaub aus; Konto-Warnung
beim Antrag nutzt jetzt available statt remaining. (Verfallsdatum bleibt in
company.settings, UI bereits vorhanden.)
- Anteilige Berechnung (Zwölftel) im Ein-/Austrittsjahr anhand neuer Felder
users.entry_date / exit_date; opt-in pro Firma (vacation_prorate_first_year).
- Teilzeit: Anspruch optional aus Arbeitstagen/Woche des WorkSchedule abgeleitet
(vacation_from_schedule), Basis vacation_default_days.
- _get_or_create_balance berechnet den Grundanspruch jetzt frisch
(_compute_entitlement); _carryover_expired/effective_available als Service-API,
Router delegiert.
Frontend: CompanySettingsPage (Jahresurlaub + Pro-rata- und Teilzeit-Toggles),
UsersPage (Ein-/Austrittsdatum im Edit-Modal), AbsencesPage ("Verfügbar" + Hinweis
bei verfallenem Resturlaub).
Migration 0036. 183/183 Tests grün. Deployed auf 137 + 164.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,36 @@
|
||||
"""Vacation entitlement: pro-rata + part-time config (agent-11 PR2)
|
||||
|
||||
Revision ID: 0036
|
||||
Revises: 0035
|
||||
Create Date: 2026-06-23
|
||||
|
||||
- users.entry_date / exit_date (Basis für anteilige Urlaubsberechnung, Zwölftel)
|
||||
- companies.vacation_default_days (Vollzeit-Grundurlaub für neue Konten)
|
||||
- companies.vacation_prorate_first_year (anteilig im Ein-/Austrittsjahr)
|
||||
- companies.vacation_from_schedule (Teilzeit-Anspruch aus WorkSchedule ableiten)
|
||||
|
||||
Resturlaub-Verfall bleibt in companies.settings (carryover_expires_month/day),
|
||||
wird in PR2 nur scharf geschaltet (effektiv verfügbarer Saldo) – keine Spalte nötig.
|
||||
"""
|
||||
from alembic import op
|
||||
|
||||
revision = "0036"
|
||||
down_revision = "0035"
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
op.execute("ALTER TABLE users ADD COLUMN IF NOT EXISTS entry_date DATE")
|
||||
op.execute("ALTER TABLE users ADD COLUMN IF NOT EXISTS exit_date DATE")
|
||||
op.execute("ALTER TABLE companies ADD COLUMN IF NOT EXISTS vacation_default_days INTEGER NOT NULL DEFAULT 30")
|
||||
op.execute("ALTER TABLE companies ADD COLUMN IF NOT EXISTS vacation_prorate_first_year BOOLEAN NOT NULL DEFAULT TRUE")
|
||||
op.execute("ALTER TABLE companies ADD COLUMN IF NOT EXISTS vacation_from_schedule BOOLEAN NOT NULL DEFAULT FALSE")
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
op.execute("ALTER TABLE companies DROP COLUMN IF EXISTS vacation_from_schedule")
|
||||
op.execute("ALTER TABLE companies DROP COLUMN IF EXISTS vacation_prorate_first_year")
|
||||
op.execute("ALTER TABLE companies DROP COLUMN IF EXISTS vacation_default_days")
|
||||
op.execute("ALTER TABLE users DROP COLUMN IF EXISTS exit_date")
|
||||
op.execute("ALTER TABLE users DROP COLUMN IF EXISTS entry_date")
|
||||
Reference in New Issue
Block a user