144 lines
4.4 KiB
Python
144 lines
4.4 KiB
Python
from asyncio.log import logger
|
|
from fastapi import APIRouter, Depends, HTTPException, status
|
|
from sqlalchemy.orm import Session
|
|
from typing import List, Dict
|
|
from datetime import datetime, timedelta
|
|
from sqlalchemy import and_
|
|
|
|
# database
|
|
from database import get_db
|
|
|
|
# schemas
|
|
from models.Doctors import Doctors
|
|
from models.Appointments import Appointments
|
|
from models.Calendar import Calenders
|
|
from schemas.ResponseSchemas import (
|
|
Doctor,
|
|
DoctorWithAppointments,
|
|
DoctorWithCalendar,
|
|
CalendarTimeSchema,
|
|
)
|
|
from schemas.CreateSchemas import DoctorCreate
|
|
from schemas.UpdateSchemas import DoctorUpdate
|
|
from enums.enums import AppointmentStatus
|
|
|
|
router = APIRouter()
|
|
|
|
|
|
@router.post("/", response_model=Doctor, status_code=status.HTTP_201_CREATED)
|
|
def create_doctor(doctor: DoctorCreate, db: Session = Depends(get_db)):
|
|
try:
|
|
db_doctor = Doctors(**doctor.model_dump())
|
|
db.add(db_doctor)
|
|
db.commit()
|
|
db.refresh(db_doctor)
|
|
return db_doctor
|
|
except Exception as e:
|
|
db.rollback()
|
|
|
|
raise HTTPException(
|
|
status_code=500,
|
|
detail=str(e.__cause__),
|
|
) from e
|
|
|
|
|
|
@router.get("/", response_model=List[DoctorWithCalendar])
|
|
def read_doctors(
|
|
doctor_name: str | None = None,
|
|
skip: int = 0,
|
|
limit: int = 100,
|
|
db: Session = Depends(get_db),
|
|
):
|
|
query = db.query(Doctors)
|
|
if doctor_name:
|
|
query = query.filter(Doctors.name.ilike(f"%{doctor_name}%"))
|
|
|
|
doctors = query.offset(skip).limit(limit).all()
|
|
return doctors
|
|
|
|
|
|
@router.get("/available-slots/{doctor_name}", response_model=Dict[str, List[str]])
|
|
def get_available_slots(
|
|
doctor_name: str | None = None,
|
|
date: str | None = datetime.now().strftime("%Y-%m-%d"),
|
|
db: Session = Depends(get_db),
|
|
):
|
|
"""
|
|
Get available slots for a doctor on a specific date.
|
|
date format: YYYY-MM-DD
|
|
"""
|
|
# Get the doctor
|
|
print(f"-----------------doctor_name: {doctor_name}")
|
|
doctor = db.query(Doctors).filter(Doctors.name.ilike(f"%{doctor_name}%")).first()
|
|
if not doctor:
|
|
raise HTTPException(status_code=404, detail="Doctor not found")
|
|
|
|
# Get all calendar slots for the doctor
|
|
calendar_slots = db.query(Calenders).filter(Calenders.doc_id == doctor.id).all()
|
|
if not calendar_slots:
|
|
return {"available_slots": []}
|
|
|
|
available_slots = [slot.time for slot in calendar_slots]
|
|
|
|
try:
|
|
target_date = datetime.strptime(date, "%Y-%m-%d").date()
|
|
except ValueError:
|
|
raise HTTPException(
|
|
status_code=400, detail="Invalid date format. Use YYYY-MM-DD"
|
|
)
|
|
|
|
# Get all appointments for the doctor on the specified date
|
|
appointments = (
|
|
db.query(Appointments)
|
|
.filter(
|
|
and_(
|
|
Appointments.doctor_id == doctor.id,
|
|
Appointments.appointment_time >= target_date,
|
|
Appointments.appointment_time < target_date + timedelta(days=1),
|
|
)
|
|
)
|
|
.all()
|
|
)
|
|
|
|
# Remove slots that have appointments
|
|
for appointment in appointments:
|
|
appointment_time = appointment.appointment_time.strftime("%H:%M")
|
|
if appointment_time in available_slots and (
|
|
not appointment.status == AppointmentStatus.COMPLETED
|
|
):
|
|
available_slots.remove(appointment_time)
|
|
|
|
return {"available_slots": available_slots}
|
|
|
|
|
|
# @router.get("/{doctor_name}", response_model=DoctorWithAppointments)
|
|
# def read_doctor(doctor_name: str, db: Session = Depends(get_db)):
|
|
# db_doctor = db.query(Doctors).filter(Doctors.name.ilike(f"%{doctor_name}%")).all()
|
|
# return db_doctor
|
|
|
|
|
|
@router.put("/{doctor_id}", response_model=Doctor)
|
|
def update_doctor(doctor_id: int, doctor: DoctorUpdate, db: Session = Depends(get_db)):
|
|
db_doctor = db.query(Doctors).filter(Doctors.id == doctor_id).first()
|
|
if db_doctor is None:
|
|
raise HTTPException(status_code=404, detail="Doctor not found")
|
|
|
|
update_data = doctor.model_dump(exclude_unset=True)
|
|
for key, value in update_data.items():
|
|
setattr(db_doctor, key, value)
|
|
|
|
db.commit()
|
|
db.refresh(db_doctor)
|
|
return db_doctor
|
|
|
|
|
|
@router.delete("/{doctor_id}", status_code=status.HTTP_204_NO_CONTENT)
|
|
def delete_doctor(doctor_id: int, db: Session = Depends(get_db)):
|
|
db_doctor = db.query(Doctors).filter(Doctors.id == doctor_id).first()
|
|
if db_doctor is None:
|
|
raise HTTPException(status_code=404, detail="Doctor not found")
|
|
|
|
db.delete(db_doctor)
|
|
db.commit()
|
|
return None
|