aggiunti trasferte, export excel, miglioramenti generali
This commit is contained in:
@@ -2,13 +2,13 @@
|
||||
User Management Routes
|
||||
Admin user CRUD and user self-service (profile, settings, password)
|
||||
"""
|
||||
from datetime import datetime
|
||||
from datetime import datetime, date
|
||||
from fastapi import APIRouter, Depends, HTTPException
|
||||
from pydantic import BaseModel, EmailStr
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from database.connection import get_db
|
||||
from database.models import User, UserRole, Office
|
||||
from database.models import User, UserRole, Office, ParkingExclusion
|
||||
from utils.auth_middleware import get_current_user, require_admin
|
||||
from utils.helpers import (
|
||||
generate_uuid, is_ldap_user, is_ldap_admin,
|
||||
@@ -54,6 +54,20 @@ class ChangePasswordRequest(BaseModel):
|
||||
new_password: str
|
||||
|
||||
|
||||
class UserExclusionCreate(BaseModel):
|
||||
start_date: date | None = None
|
||||
end_date: date | None = None
|
||||
notes: str | None = None
|
||||
|
||||
|
||||
class UserExclusionResponse(BaseModel):
|
||||
id: str
|
||||
start_date: date | None
|
||||
end_date: date | None
|
||||
notes: str | None
|
||||
is_excluded: bool = True
|
||||
|
||||
|
||||
class UserResponse(BaseModel):
|
||||
id: str
|
||||
email: str
|
||||
@@ -332,3 +346,105 @@ def change_password(data: ChangePasswordRequest, db: Session = Depends(get_db),
|
||||
db.commit()
|
||||
config.logger.info(f"User {current_user.email} changed password")
|
||||
return {"message": "Password changed"}
|
||||
|
||||
|
||||
# Exclusion Management (Self-Service)
|
||||
# Exclusion Management (Self-Service)
|
||||
@router.get("/me/exclusion", response_model=list[UserExclusionResponse])
|
||||
def get_my_exclusions(db: Session = Depends(get_db), current_user=Depends(get_current_user)):
|
||||
"""Get current user's parking exclusions"""
|
||||
if not current_user.office_id:
|
||||
return []
|
||||
|
||||
exclusions = db.query(ParkingExclusion).filter(
|
||||
ParkingExclusion.user_id == current_user.id,
|
||||
ParkingExclusion.office_id == current_user.office_id
|
||||
).all()
|
||||
|
||||
return [
|
||||
{
|
||||
"id": e.id,
|
||||
"start_date": e.start_date,
|
||||
"end_date": e.end_date,
|
||||
"notes": e.notes,
|
||||
"is_excluded": True
|
||||
}
|
||||
for e in exclusions
|
||||
]
|
||||
|
||||
|
||||
@router.post("/me/exclusion")
|
||||
def create_my_exclusion(data: UserExclusionCreate, db: Session = Depends(get_db), current_user=Depends(get_current_user)):
|
||||
"""Create new parking exclusion for current user"""
|
||||
if not current_user.office_id:
|
||||
raise HTTPException(status_code=400, detail="User is not assigned to an office")
|
||||
|
||||
if data.start_date and data.end_date and data.end_date < data.start_date:
|
||||
raise HTTPException(status_code=400, detail="End date must be after start date")
|
||||
|
||||
if data.end_date and not data.start_date:
|
||||
raise HTTPException(status_code=400, detail="Start date is required if an end date is specified")
|
||||
|
||||
exclusion = ParkingExclusion(
|
||||
id=generate_uuid(),
|
||||
office_id=current_user.office_id,
|
||||
user_id=current_user.id,
|
||||
start_date=data.start_date,
|
||||
end_date=data.end_date,
|
||||
notes=data.notes or "Auto-esclusione utente",
|
||||
created_at=datetime.utcnow()
|
||||
)
|
||||
db.add(exclusion)
|
||||
db.commit()
|
||||
return {"message": "Exclusion created", "id": exclusion.id}
|
||||
|
||||
|
||||
@router.put("/me/exclusion/{exclusion_id}")
|
||||
def update_my_exclusion(exclusion_id: str, data: UserExclusionCreate, db: Session = Depends(get_db), current_user=Depends(get_current_user)):
|
||||
"""Update specific parking exclusion for current user"""
|
||||
if not current_user.office_id:
|
||||
raise HTTPException(status_code=400, detail="User is not assigned to an office")
|
||||
|
||||
exclusion = db.query(ParkingExclusion).filter(
|
||||
ParkingExclusion.id == exclusion_id,
|
||||
ParkingExclusion.user_id == current_user.id,
|
||||
ParkingExclusion.office_id == current_user.office_id
|
||||
).first()
|
||||
|
||||
if not exclusion:
|
||||
raise HTTPException(status_code=404, detail="Exclusion not found")
|
||||
|
||||
if data.start_date and data.end_date and data.end_date < data.start_date:
|
||||
raise HTTPException(status_code=400, detail="End date must be after start date")
|
||||
|
||||
if data.end_date and not data.start_date:
|
||||
raise HTTPException(status_code=400, detail="Start date is required if an end date is specified")
|
||||
|
||||
exclusion.start_date = data.start_date
|
||||
exclusion.end_date = data.end_date
|
||||
if data.notes is not None:
|
||||
exclusion.notes = data.notes
|
||||
|
||||
exclusion.updated_at = datetime.utcnow()
|
||||
db.commit()
|
||||
return {"message": "Exclusion updated", "id": exclusion.id}
|
||||
|
||||
|
||||
@router.delete("/me/exclusion/{exclusion_id}")
|
||||
def delete_my_exclusion(exclusion_id: str, db: Session = Depends(get_db), current_user=Depends(get_current_user)):
|
||||
"""Remove specific parking exclusion for current user"""
|
||||
if not current_user.office_id:
|
||||
raise HTTPException(status_code=400, detail="User is not assigned to an office")
|
||||
|
||||
exclusion = db.query(ParkingExclusion).filter(
|
||||
ParkingExclusion.id == exclusion_id,
|
||||
ParkingExclusion.user_id == current_user.id,
|
||||
ParkingExclusion.office_id == current_user.office_id
|
||||
).first()
|
||||
|
||||
if not exclusion:
|
||||
raise HTTPException(status_code=404, detail="Exclusion not found")
|
||||
|
||||
db.delete(exclusion)
|
||||
db.commit()
|
||||
return {"message": "Exclusion removed"}
|
||||
|
||||
Reference in New Issue
Block a user