a63b0e835f
- Backend: Model HoursPayout, Schema, Router GET/POST/DELETE
- GET /hr/payouts: HR/Admin sehen alle, Employee/Manager nur eigene
- POST /hr/payouts: reduziert OvertimeBalance.taken_hours sofort
- DELETE /hr/payouts/{id}: storniert und bucht Stunden zurück
- AuditLog-Einträge bei Anlegen und Stornieren
- Migration 0030: hours_payouts Tabelle
- Frontend: /hr/payouts Seite (lila, 💸) mit Filter, Tabelle, Modal
- Modal zeigt verfügbares Überstundenguthaben + Warnung bei Überziehung
- Navigation: Stunden-Auszahlung (HR/COMPANY_ADMIN/SUPER_ADMIN)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
34 lines
930 B
Python
34 lines
930 B
Python
import uuid
|
|
from datetime import datetime
|
|
from decimal import Decimal
|
|
from pydantic import BaseModel, Field
|
|
|
|
|
|
class HoursPayoutCreate(BaseModel):
|
|
user_id: uuid.UUID
|
|
hours: Decimal = Field(gt=0, le=999.99, decimal_places=2)
|
|
period_year: int | None = Field(None, ge=2000, le=2100)
|
|
period_month: int | None = Field(None, ge=1, le=12)
|
|
note: str | None = Field(None, max_length=500)
|
|
|
|
|
|
class HoursPayoutOut(BaseModel):
|
|
model_config = {"from_attributes": True}
|
|
|
|
id: uuid.UUID
|
|
company_id: uuid.UUID
|
|
user_id: uuid.UUID
|
|
user_name: str # Computed: first_name + last_name (wird im Router gesetzt)
|
|
hours: Decimal
|
|
period_year: int | None
|
|
period_month: int | None
|
|
note: str | None
|
|
created_by: uuid.UUID
|
|
created_by_name: str # Computed im Router
|
|
created_at: datetime
|
|
|
|
|
|
class HoursPayoutListResponse(BaseModel):
|
|
payouts: list[HoursPayoutOut]
|
|
total_count: int
|