feat: clinic approval flow

This commit is contained in:
deepvasoya 2025-05-19 19:03:58 +05:30
parent 205e423b56
commit a00c3884c4
18 changed files with 396 additions and 52 deletions

View File

@ -11,7 +11,7 @@ from .endpoints import clinics, doctors, calender, appointments, patients, admin
api_router = APIRouter() api_router = APIRouter()
# api_router.include_router(twilio.router, prefix="/twilio") # api_router.include_router(twilio.router, prefix="/twilio")
api_router.include_router(clinics.router, prefix="/clinics", tags=["clinics"]) api_router.include_router(clinics.router, prefix="/clinics", tags=["clinics"], dependencies=[Depends(auth_required)])
api_router.include_router(doctors.router, prefix="/doctors", tags=["doctors"]) api_router.include_router(doctors.router, prefix="/doctors", tags=["doctors"])

View File

@ -1,8 +1,13 @@
from fastapi import APIRouter, status from fastapi import APIRouter, Request, status
from services.clinicServices import ClinicServices
from schemas.UpdateSchemas import ClinicStatusUpdate
from schemas.ApiResponse import ApiResponse
router = APIRouter() router = APIRouter()
@router.get("/", status_code=status.HTTP_200_OK) @router.put("/clinic/status")
def get_admin(): def update_clinic_status(req:Request, data: ClinicStatusUpdate):
return {"message": "Admin"} response = ClinicServices().update_clinic_status(req.state.user, data.clinic_id, data.status)
return ApiResponse(data=response, message="Clinic status updated successfully")

View File

@ -1,29 +1,33 @@
from typing import List from typing import List, Literal, Union
from fastapi import APIRouter, HTTPException, status from fastapi import APIRouter, status, Request
# database
from database import get_db
# schemas # schemas
from schemas.ResponseSchemas import Clinic from schemas.ResponseSchemas import Clinic
from schemas.UpdateSchemas import ClinicUpdate from schemas.UpdateSchemas import ClinicUpdate
from models.Clinics import Clinics
# services # services
from services.clinicServices import ClinicServices from services.clinicServices import ClinicServices
# Constants # Constants
from schemas.ApiResponse import ApiResponse from schemas.ApiResponse import ApiResponse
from utils.constants import DEFAULT_SKIP, DEFAULT_LIMIT from interface.common_response import CommonResponse
from utils.constants import DEFAULT_PAGE, DEFAULT_SKIP, DEFAULT_LIMIT
router = APIRouter() router = APIRouter()
@router.get("/", response_model=List[Clinic]) @router.get("/")
async def get_clinics( async def get_clinics(
skip: int = DEFAULT_SKIP, limit: int = DEFAULT_LIMIT req:Request,
page: int = DEFAULT_PAGE,
limit: int = DEFAULT_LIMIT,
filter_type: Union[Literal["UNREGISTERED"], Literal["REGISTERED"]] = "UNREGISTERED",
search:str = ""
): ):
clinics = ClinicServices().get_clinics(skip, limit) if page < 1:
page = 1
offset = (page - 1) * limit
clinics = ClinicServices().get_clinics(req.state.user, limit, offset, filter_type, search)
return ApiResponse(data=clinics, message="Clinics retrieved successfully" ) return ApiResponse(data=clinics, message="Clinics retrieved successfully" )
@router.get("/latest-id") @router.get("/latest-id")
@ -31,26 +35,26 @@ async def get_latest_clinic_id():
clinic_id = ClinicServices().get_latest_clinic_id() clinic_id = ClinicServices().get_latest_clinic_id()
return ApiResponse(data=clinic_id, message="Latest clinic ID retrieved successfully") return ApiResponse(data=clinic_id, message="Latest clinic ID retrieved successfully")
@router.get("/verified-files/{clinic_id}")
async def get_verified_files(clinic_id: int):
clinic = ClinicServices().get_clinic_by_id(clinic_id)
return ApiResponse(data=clinic, message="Clinic retrieved successfully")
@router.get("/{clinic_id}") @router.get("/{clinic_id}")
async def get_clinic(clinic_id: int): async def get_clinic(clinic_id: int):
clinic = ClinicServices().get_clinic_by_id(clinic_id) clinic = ClinicServices().get_clinic_by_id(clinic_id)
return ApiResponse(data=clinic, message="Clinic retrieved successfully") return ApiResponse(data=clinic, message="Clinic retrieved successfully")
@router.put("/{clinic_id}")
@router.put("/{clinic_id}", response_model=Clinic)
async def update_clinic( async def update_clinic(
req:Request,
clinic_id: int, clinic: ClinicUpdate clinic_id: int, clinic: ClinicUpdate
): ):
clinic = ClinicServices().update_clinic(clinic_id, clinic) clinic = ClinicServices().update_clinic(req.state.user, clinic_id, clinic)
return ApiResponse(data=clinic, message="Clinic updated successfully") return ApiResponse(data=clinic, message="Clinic updated successfully")
@router.delete("/{clinic_id}", status_code=status.HTTP_204_NO_CONTENT) @router.delete("/{clinic_id}", status_code=status.HTTP_204_NO_CONTENT)
async def delete_clinic(clinic_id: int): async def delete_clinic(clinic_id: int):
db_clinic = db.query(Clinics).where(Clinics.id == clinic_id).first() ClinicServices().delete_clinic(clinic_id)
if db_clinic is None: return ApiResponse(message="Clinic deleted successfully")
raise HTTPException(status_code=404, detail="Clinic not found")
db.delete(db_clinic)
db.commit()
return None

View File

@ -2,6 +2,7 @@ from fastapi import APIRouter, Request
from services.dashboardService import DashboardService from services.dashboardService import DashboardService
from schemas.ApiResponse import ApiResponse from schemas.ApiResponse import ApiResponse
from enums.enums import UserType from enums.enums import UserType
from schemas.CreateSchemas import SignupPricingMasterCreate
router = APIRouter() router = APIRouter()
@ -9,3 +10,15 @@ router = APIRouter()
async def get_clinic_doctor_status_count(req:Request): async def get_clinic_doctor_status_count(req:Request):
counts = DashboardService().get_dashboard_counts(isSuperAdmin=req.state.user["userType"] == UserType.SUPER_ADMIN) counts = DashboardService().get_dashboard_counts(isSuperAdmin=req.state.user["userType"] == UserType.SUPER_ADMIN)
return ApiResponse(data=counts, message="Counts fetched successfully") return ApiResponse(data=counts, message="Counts fetched successfully")
@router.post("/signup-pricing-master")
async def update_signup_pricing_master(req:Request, signup_pricing_master:SignupPricingMasterCreate):
user = req.state.user
response = DashboardService().update_signup_pricing_master(user, signup_pricing_master)
return ApiResponse(data=response, message="Signup pricing master updated successfully")
@router.get("/signup-pricing-master")
async def get_signup_pricing_master():
pricing = DashboardService().get_signup_pricing_master()
return ApiResponse(data=pricing, message="Signup pricing master fetched successfully")

View File

@ -0,0 +1,32 @@
"""file-verification-table
Revision ID: 497238c0338d
Revises: ad47f4af583e
Create Date: 2025-05-19 16:34:54.211429
"""
from typing import Sequence, Union
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision: str = '497238c0338d'
down_revision: Union[str, None] = 'ad47f4af583e'
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
def upgrade() -> None:
"""Upgrade schema."""
# ### commands auto generated by Alembic - please adjust! ###
op.add_column('clinic_file_verifications', sa.Column('rejection_reason', sa.String(length=255), nullable=True))
# ### end Alembic commands ###
def downgrade() -> None:
"""Downgrade schema."""
# ### commands auto generated by Alembic - please adjust! ###
op.drop_column('clinic_file_verifications', 'rejection_reason')
# ### end Alembic commands ###

View File

@ -0,0 +1,32 @@
"""file-verification-table
Revision ID: ec157808ef2a
Revises: 497238c0338d
Create Date: 2025-05-19 17:16:52.137111
"""
from typing import Sequence, Union
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision: str = 'ec157808ef2a'
down_revision: Union[str, None] = '497238c0338d'
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
def upgrade() -> None:
"""Upgrade schema."""
# ### commands auto generated by Alembic - please adjust! ###
op.add_column('clinic_file_verifications', sa.Column('logo_is_verified', sa.Boolean(), nullable=True))
# ### end Alembic commands ###
def downgrade() -> None:
"""Downgrade schema."""
# ### commands auto generated by Alembic - please adjust! ###
op.drop_column('clinic_file_verifications', 'logo_is_verified')
# ### end Alembic commands ###

View File

@ -0,0 +1,18 @@
from database import Base
from sqlalchemy import Column, Integer, Boolean, ForeignKey, String
from .CustomBase import CustomBase
from sqlalchemy.orm import relationship
class ClinicFileVerifications(Base, CustomBase):
__tablename__ = "clinic_file_verifications"
id = Column(Integer, primary_key=True, index=True)
clinic_id = Column(Integer, ForeignKey("clinics.id"), nullable=False)
logo_is_verified = Column(Boolean, default=False)
abn_doc_is_verified = Column(Boolean, default=False)
contract_doc_is_verified = Column(Boolean, default=False)
last_changed_by = Column(Integer, ForeignKey("users.id"), nullable=False)
rejection_reason = Column(String(255), nullable=True)
clinic = relationship("Clinics", back_populates="clinic_file_verifications")
last_changed_by_user = relationship("Users", back_populates="clinic_file_verifications")

View File

@ -45,3 +45,4 @@ class Clinics(Base, CustomBase):
doctors = relationship("Doctors", back_populates="clinic") doctors = relationship("Doctors", back_populates="clinic")
clinicDoctors = relationship("ClinicDoctors", back_populates="clinic") clinicDoctors = relationship("ClinicDoctors", back_populates="clinic")
creator = relationship("Users", back_populates="created_clinics") creator = relationship("Users", back_populates="created_clinics")
clinic_file_verifications = relationship("ClinicFileVerifications", back_populates="clinic")

View File

@ -0,0 +1,11 @@
from sqlalchemy import Column, Integer, Numeric
from database import Base
from .CustomBase import CustomBase
class SignupPricingMaster(Base, CustomBase):
__tablename__ = "signup_pricing_master"
id = Column(Integer, primary_key=True, index=True)
setup_fees = Column(Numeric(precision=10, scale=2))
subscription_fees = Column(Numeric(precision=10, scale=2))
per_call_charges = Column(Numeric(precision=10, scale=2))

View File

@ -25,3 +25,4 @@ class Users(Base, CustomBase):
# Clinics created by this user # Clinics created by this user
created_clinics = relationship("Clinics", back_populates="creator") created_clinics = relationship("Clinics", back_populates="creator")
clinic_file_verifications = relationship("ClinicFileVerifications", back_populates="last_changed_by_user")

View File

@ -11,6 +11,8 @@ from .Notifications import Notifications
from .CallTranscripts import CallTranscripts from .CallTranscripts import CallTranscripts
from .Fcm import Fcm from .Fcm import Fcm
from .BlockedEmail import BlockedEmail from .BlockedEmail import BlockedEmail
from .SignupPricingMaster import SignupPricingMaster
from .ClinicFileVerifications import ClinicFileVerifications
__all__ = [ __all__ = [
"Users", "Users",
@ -26,4 +28,6 @@ __all__ = [
"CallTranscripts", "CallTranscripts",
"Fcm", "Fcm",
"BlockedEmail", "BlockedEmail",
"SignupPricingMaster",
"ClinicFileVerifications"
] ]

View File

@ -13,6 +13,17 @@ class SNSBase(BaseModel):
Message: str Message: str
class ClinicFileVerificationBase(BaseModel):
abn_doc_is_verified: Optional[bool] = None
contract_doc_is_verified: Optional[bool] = None
logo_is_verified: Optional[bool] = None
last_changed_by: Optional[int] = None
class SignupPricingMasterBase(BaseModel):
setup_fees: Optional[float] = None
subscription_fees: Optional[float] = None
per_call_charges: Optional[float] = None
class AuthBase(BaseModel): class AuthBase(BaseModel):
email: EmailStr email: EmailStr

View File

@ -25,6 +25,10 @@ class CalendarCreate(CalendarBase):
pass pass
class SignupPricingMasterCreate(SignupPricingMasterBase):
pass
class AppointmentCreateWithNames(BaseModel): class AppointmentCreateWithNames(BaseModel):
doctor_name: str doctor_name: str
patient_name: str patient_name: str

View File

@ -1,5 +1,7 @@
from datetime import datetime from datetime import datetime
from typing import List from typing import Any, List, Optional
from enums.enums import ClinicStatus
from .BaseSchemas import * from .BaseSchemas import *
from pydantic import Field from pydantic import Field
@ -8,6 +10,7 @@ class Clinic(ClinicBase):
id: int id: int
create_time: datetime create_time: datetime
update_time: datetime update_time: datetime
status: ClinicStatus
class Config: class Config:
orm_mode = True orm_mode = True
@ -22,6 +25,15 @@ class ClinicDoctorResponse(ClinicDoctorBase):
orm_mode = True orm_mode = True
class SignupPricingMasterResponse(SignupPricingMasterBase):
id: int
create_time: datetime
update_time: datetime
class Config:
orm_mode = True
class UserResponse(UserBase): class UserResponse(UserBase):
id: int id: int
create_time: datetime create_time: datetime

View File

@ -6,7 +6,6 @@ class ClinicUpdate(BaseModel):
name: Optional[str] = None name: Optional[str] = None
address: Optional[str] = None address: Optional[str] = None
phone: Optional[str] = None phone: Optional[str] = None
status: Optional[ClinicStatus] = None
integration: Optional[Integration] = None integration: Optional[Integration] = None
pms_id: Optional[str] = None pms_id: Optional[str] = None
practice_name: Optional[str] = None practice_name: Optional[str] = None
@ -29,6 +28,14 @@ class ClinicUpdate(BaseModel):
general_info: Optional[str] = None general_info: Optional[str] = None
class ClinicStatusUpdate(BaseModel):
clinic_id: int
status: ClinicStatus
rejection_reason: Optional[str] = None
class SignupPricingMasterUpdate(SignupPricingMasterBase):
pass
class DoctorUpdate(BaseModel): class DoctorUpdate(BaseModel):
name: Optional[str] = None name: Optional[str] = None
age: Optional[int] = None age: Optional[int] = None

View File

@ -1,51 +1,145 @@
from database import get_db from database import get_db
from sqlalchemy.orm import Session from sqlalchemy.orm import Session, joinedload
from models import Clinics from models import Clinics
from schemas.UpdateSchemas import ClinicUpdate from schemas.UpdateSchemas import ClinicStatusUpdate, ClinicUpdate
from schemas.ResponseSchemas import Clinic from schemas.ResponseSchemas import Clinic
from typing import List from typing import List, Literal, Union
from exceptions import ResourceNotFoundException from exceptions import ResourceNotFoundException
from enums.enums import ClinicStatus from enums.enums import ClinicStatus, UserType
from exceptions.unauthorized_exception import UnauthorizedException
from interface.common_response import CommonResponse
from sqlalchemy import or_,func, case
from services.s3Service import get_signed_url
from models import ClinicFileVerifications
from schemas.BaseSchemas import ClinicFileVerificationBase
class ClinicServices: class ClinicServices:
def __init__(self): def __init__(self):
self.db: Session = next(get_db()) self.db: Session = next(get_db())
def get_clinics(self, limit:int, offset:int) -> List[Clinic]: def get_clinics(self, user, limit:int, offset:int, filter_type: Union[Literal["UNREGISTERED"], Literal["REGISTERED"]] = "UNREGISTERED", search:str = ""):
clinics = self.db.query(Clinics).limit(limit).offset(offset).all()
if user["userType"] != UserType.SUPER_ADMIN:
raise UnauthorizedException("You are not authorized to get clinics")
clinics_query = self.db.query(Clinics)
if filter_type == "UNREGISTERED":
clinics_query = clinics_query.filter(Clinics.status != ClinicStatus.ACTIVE)
elif filter_type == "REGISTERED":
clinics_query = clinics_query.filter(Clinics.status == ClinicStatus.ACTIVE)
if search:
clinics_query = clinics_query.filter(
or_(
Clinics.name.contains(search),
Clinics.email.contains(search),
Clinics.phone.contains(search),
Clinics.address.contains(search)
)
)
clinics = clinics_query.limit(limit).offset(offset).all()
# Get all counts in a single optimized query
from sqlalchemy import text
count_query = text("""
SELECT
COUNT(*) as total,
COUNT(CASE WHEN status = 'ACTIVE' THEN 1 END) as active,
COUNT(CASE WHEN status = 'REJECTED' THEN 1 END) as rejected
FROM clinics
""")
result = self.db.execute(count_query).first()
totalClinics = result.total or 0
totalRegisteredClinics = result.active or 0
totalRejectedClinics = result.rejected or 0
clinic_response = [Clinic(**clinic.__dict__.copy()) for clinic in clinics] clinic_response = [Clinic(**clinic.__dict__.copy()) for clinic in clinics]
return clinic_response for clinic in clinic_response:
clinic.logo = get_signed_url(clinic.logo) if clinic.logo else None
clinic_response_with_total = {
"clinics": clinic_response,
"totalRegisteredClinics": totalRegisteredClinics,
"totalRejectedClinics": totalRejectedClinics,
}
response = CommonResponse(data=clinic_response_with_total, total=totalClinics)
return response
def get_latest_clinic_id(self) -> int: def get_latest_clinic_id(self) -> int:
clinic = self.db.query(Clinics).order_by(Clinics.id.desc()).first() clinic = self.db.query(Clinics).order_by(Clinics.id.desc()).first()
return clinic.id if clinic else 0 return clinic.id if clinic else 0
def get_clinic_by_id(self, clinic_id: int) -> Clinic: def get_clinic_by_id(self, clinic_id: int):
clinic = self.db.query(Clinics).filter(Clinics.id == clinic_id).first() try:
clinic = self.db.query(Clinics).options(joinedload(Clinics.creator)).filter(Clinics.id == clinic_id).first()
if clinic is None: if clinic is None:
raise ResourceNotFoundException("Clinic not found") raise ResourceNotFoundException("Clinic not found")
clinic_response = Clinic(**clinic.__dict__.copy()) clinic_response = Clinic(**clinic.__dict__.copy())
return clinic_response
def update_clinic(self, clinic_id: int, clinic_data: ClinicUpdate): clinic_response.logo = get_signed_url(clinic_response.logo) if clinic_response.logo else None
clinic_response.abn_doc = get_signed_url(clinic_response.abn_doc) if clinic_response.abn_doc else None
clinic_response.contract_doc = get_signed_url(clinic_response.contract_doc) if clinic_response.contract_doc else None
clinic_resp = {
"clinic": clinic_response,
"creator": {
"name": clinic.creator.username,
"email": clinic.creator.email,
"phone": clinic.creator.mobile,
"designation": clinic.creator.clinicRole
},
"clinic_files": self.get_clinic_files(clinic_id)
}
return clinic_resp
except Exception as e:
raise Exception(e)
def get_clinic_files(self, clinic_id: int):
clinic_files = self.db.query(ClinicFileVerifications).filter(ClinicFileVerifications.clinic_id == clinic_id).first()
if clinic_files is None:
raise ResourceNotFoundException("Clinic not found")
response = ClinicFileVerificationBase(**clinic_files.__dict__.copy())
return response
def update_clinic(self, user, clinic_id: int, clinic_data: ClinicUpdate):
clinic = self.db.query(Clinics).filter(Clinics.id == clinic_id).first() clinic = self.db.query(Clinics).filter(Clinics.id == clinic_id).first()
if clinic is None: if clinic is None:
raise ResourceNotFoundException("Clinic not found") raise ResourceNotFoundException("Clinic not found")
if clinic.creator_id != user["id"]:
raise UnauthorizedException("You are not authorized to update this clinic")
update_data = clinic_data.model_dump(exclude_unset=True) update_data = clinic_data.model_dump(exclude_unset=True)
for key, value in update_data.items(): for key, value in update_data.items():
setattr(clinic, key, value) setattr(clinic, key, value)
self.db.add(clinic) self.db.add(clinic)
self.db.commit() self.db.commit()
self.db.refresh(clinic) self.db.refresh(clinic)
return Clinic(**clinic.__dict__.copy())
clinic_response = Clinic(**clinic.__dict__.copy())
clinic_response.logo = get_signed_url(clinic_response.logo) if clinic_response.logo else None
return clinic_response
def delete_clinic(self, clinic_id: int): def delete_clinic(self, clinic_id: int):
clinic = self.db.query(Clinics).filter(Clinics.id == clinic_id).first() clinic = self.db.query(Clinics).filter(Clinics.id == clinic_id).first()
@ -95,3 +189,28 @@ class ClinicServices:
counts[key] = count counts[key] = count
return counts return counts
def update_clinic_status(self, user, clinic_id: int, status: ClinicStatus):
if user["userType"] != UserType.SUPER_ADMIN:
raise UnauthorizedException("You are not authorized to update clinic status")
clinic = self.db.query(Clinics).filter(Clinics.id == clinic_id).first()
if clinic is None:
raise ResourceNotFoundException("Clinic not found")
clinic.status = status
self.db.add(clinic)
self.db.commit()
self.db.refresh(clinic)
clinic_response = Clinic(**clinic.__dict__.copy())
# if rejected then email to clinic creator
if clinic.status == ClinicStatus.REJECTED:
pass
return clinic_response

View File

@ -1,6 +1,12 @@
from database import get_db from database import get_db
from services.clinicDoctorsServices import ClinicDoctorsServices from services.clinicDoctorsServices import ClinicDoctorsServices
from services.clinicServices import ClinicServices from services.clinicServices import ClinicServices
from schemas.BaseSchemas import SignupPricingMasterBase
from schemas.ResponseSchemas import SignupPricingMasterResponse
from models.SignupPricingMaster import SignupPricingMaster
from exceptions import UnauthorizedException
from enums.enums import UserType
from exceptions import ResourceNotFoundException
class DashboardService: class DashboardService:
def __init__(self): def __init__(self):
@ -15,3 +21,54 @@ class DashboardService:
else: else:
clinicDoctorsCount = self.clinicDoctorsServices.get_doctor_status_count() clinicDoctorsCount = self.clinicDoctorsServices.get_doctor_status_count()
return clinicDoctorsCount return clinicDoctorsCount
def update_signup_pricing_master(
self, user, pricing_data: SignupPricingMasterBase
):
if user["userType"] != UserType.SUPER_ADMIN:
raise UnauthorizedException(
"You are not authorized to update signup pricing master"
)
existing_pricing = self.db.query(SignupPricingMaster).first()
if existing_pricing is None:
# Create new record
new_pricing = SignupPricingMaster(
**pricing_data.model_dump()
)
self.db.add(new_pricing)
self.db.commit()
self.db.refresh(new_pricing)
response = SignupPricingMasterResponse(
**new_pricing.__dict__.copy()
)
return response
else:
# Update existing record with values from the request
existing_pricing.setup_fees = pricing_data.setup_fees
existing_pricing.subscription_fees = pricing_data.subscription_fees
existing_pricing.per_call_charges = pricing_data.per_call_charges
self.db.commit()
self.db.refresh(existing_pricing)
response = SignupPricingMasterResponse(
**existing_pricing.__dict__.copy()
)
return response
def get_signup_pricing_master(self):
signup_pricing_master = self.db.query(SignupPricingMaster).first()
if signup_pricing_master is None:
raise ResourceNotFoundException("Signup pricing master not found")
response = SignupPricingMasterResponse(
**signup_pricing_master.__dict__.copy()
)
return response

View File

@ -11,10 +11,12 @@ from schemas.UpdateSchemas import UserUpdate
from exceptions.unauthorized_exception import UnauthorizedException from exceptions.unauthorized_exception import UnauthorizedException
from interface.common_response import CommonResponse from interface.common_response import CommonResponse
from exceptions.business_exception import BusinessValidationException from exceptions.business_exception import BusinessValidationException
from models import ClinicFileVerifications
from utils.password_utils import hash_password from utils.password_utils import hash_password
from schemas.CreateSchemas import UserCreate from schemas.CreateSchemas import UserCreate
from exceptions.resource_not_found_exception import ResourceNotFoundException from exceptions.resource_not_found_exception import ResourceNotFoundException
from exceptions.db_exceptions import DBExceptionHandler from exceptions.db_exceptions import DBExceptionHandler
from sqlalchemy.orm import joinedload
class UserServices: class UserServices:
@ -98,6 +100,18 @@ class UserServices:
# Add clinic to database # Add clinic to database
self.db.add(new_clinic) self.db.add(new_clinic)
self.db.flush()
# Create clinic files
clinic_files = ClinicFileVerifications(
clinic_id=new_clinic.id,
abn_doc_is_verified=False,
contract_doc_is_verified=False,
last_changed_by=new_user.id
)
# Add clinic files to database
self.db.add(clinic_files)
# Now commit both user and clinic in a single transaction # Now commit both user and clinic in a single transaction
self.db.commit() self.db.commit()
@ -114,7 +128,6 @@ class UserServices:
def get_user(self, user_id) -> UserResponse: def get_user(self, user_id) -> UserResponse:
try: try:
# Query the user by ID and explicitly load the created clinics relationship # Query the user by ID and explicitly load the created clinics relationship
from sqlalchemy.orm import joinedload
user = self.db.query(Users).options(joinedload(Users.created_clinics)).filter(Users.id == user_id).first() user = self.db.query(Users).options(joinedload(Users.created_clinics)).filter(Users.id == user_id).first()
if not user: if not user: