Files
aars/backend/schemas.py
T

188 lines
4.2 KiB
Python

from pydantic import BaseModel, EmailStr, Field
from typing import Optional, List, Dict, Any
from datetime import date, time, datetime
# ============ Auth ============
class LoginRequest(BaseModel):
email: str
password: str
class TokenResponse(BaseModel):
access_token: str
token_type: str = "bearer"
class UserResponse(BaseModel):
id: int
email: str
name: str
role: str
class Config:
from_attributes = True
# ============ Attendance ============
class AttendanceBase(BaseModel):
employee_id: str
employee_name: str
department: Optional[str] = None
date: date
check_in: Optional[time] = None
check_out: Optional[time] = None
overtime_hours: float = 0
leave_type: Optional[str] = None
leave_hours: float = 0
status: str
remarks: Optional[str] = None
custom_fields: Dict[str, Any] = {}
class AttendanceCreate(AttendanceBase):
pass
class AttendanceUpdate(BaseModel):
employee_id: Optional[str] = None
employee_name: Optional[str] = None
department: Optional[str] = None
date: Optional[date] = None
check_in: Optional[time] = None
check_out: Optional[time] = None
overtime_hours: Optional[float] = None
leave_type: Optional[str] = None
leave_hours: Optional[float] = None
status: Optional[str] = None
remarks: Optional[str] = None
custom_fields: Optional[Dict[str, Any]] = None
class AttendanceResponse(AttendanceBase):
id: int
created_by: Optional[int] = None
created_at: datetime
updated_at: datetime
class Config:
from_attributes = True
# ============ Accident ============
class AccidentBase(BaseModel):
date: date
time: Optional[time] = None
location: str
employee_name: str
employee_id: Optional[str] = None
department: Optional[str] = None
description: str
severity: str
medical_report: Optional[str] = None
action_taken: Optional[str] = None
responsible_person: Optional[str] = None
custom_fields: Dict[str, Any] = {}
class AccidentCreate(AccidentBase):
pass
class AccidentUpdate(BaseModel):
date: Optional[date] = None
time: Optional[time] = None
location: Optional[str] = None
employee_name: Optional[str] = None
employee_id: Optional[str] = None
department: Optional[str] = None
description: Optional[str] = None
severity: Optional[str] = None
medical_report: Optional[str] = None
action_taken: Optional[str] = None
responsible_person: Optional[str] = None
custom_fields: Optional[Dict[str, Any]] = None
class AccidentResponse(AccidentBase):
id: int
created_by: Optional[int] = None
created_at: datetime
updated_at: datetime
class Config:
from_attributes = True
# ============ Custom Fields ============
class CustomFieldBase(BaseModel):
field_name: str
field_type: str
field_key: str
required: bool = False
options: List[str] = []
order: int = 0
class CustomFieldCreate(CustomFieldBase):
pass
class CustomFieldResponse(CustomFieldBase):
id: int
class Config:
from_attributes = True
# ============ Dashboard ============
class AttendanceStats(BaseModel):
total: int
today: int
this_month: int
by_status: Dict[str, int]
by_department: Dict[str, int]
trend: List[Dict[str, Any]]
class AccidentStats(BaseModel):
total: int
this_month: int
unresolved: int
by_severity: Dict[str, int]
recent: List[AccidentResponse]
# ============ Import ============
class ImportRequest(BaseModel):
section: str # "attendance" or "accident"
update_existing: bool = True
class ImportResult(BaseModel):
created: int
updated: int
skipped: int
errors: List[str]
# ============ Pagination / Filter ============
class FilterParams(BaseModel):
page: int = 1
per_page: int = 20
sort_by: Optional[str] = None
sort_order: Optional[str] = "asc" # asc or desc
search: Optional[str] = None
date_from: Optional[date] = None
date_to: Optional[date] = None
department: Optional[str] = None
status: Optional[str] = None
class PaginatedResponse(BaseModel):
items: List[Any]
total: int
page: int
per_page: int
total_pages: int