feat: clinic approval flow
This commit is contained in:
+137
-18
@@ -1,51 +1,145 @@
|
||||
from database import get_db
|
||||
from sqlalchemy.orm import Session
|
||||
from sqlalchemy.orm import Session, joinedload
|
||||
from models import Clinics
|
||||
from schemas.UpdateSchemas import ClinicUpdate
|
||||
from schemas.UpdateSchemas import ClinicStatusUpdate, ClinicUpdate
|
||||
from schemas.ResponseSchemas import Clinic
|
||||
from typing import List
|
||||
from typing import List, Literal, Union
|
||||
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:
|
||||
def __init__(self):
|
||||
self.db: Session = next(get_db())
|
||||
|
||||
def get_clinics(self, limit:int, offset:int) -> List[Clinic]:
|
||||
clinics = self.db.query(Clinics).limit(limit).offset(offset).all()
|
||||
def get_clinics(self, user, limit:int, offset:int, filter_type: Union[Literal["UNREGISTERED"], Literal["REGISTERED"]] = "UNREGISTERED", search:str = ""):
|
||||
|
||||
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]
|
||||
|
||||
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:
|
||||
clinic = self.db.query(Clinics).order_by(Clinics.id.desc()).first()
|
||||
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):
|
||||
try:
|
||||
clinic = self.db.query(Clinics).options(joinedload(Clinics.creator)).filter(Clinics.id == clinic_id).first()
|
||||
|
||||
if clinic is None:
|
||||
raise ResourceNotFoundException("Clinic not found")
|
||||
|
||||
clinic_response = Clinic(**clinic.__dict__.copy())
|
||||
|
||||
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()
|
||||
|
||||
if clinic is None:
|
||||
raise ResourceNotFoundException("Clinic not found")
|
||||
|
||||
clinic_response = Clinic(**clinic.__dict__.copy())
|
||||
return clinic_response
|
||||
|
||||
def update_clinic(self, clinic_id: int, clinic_data: ClinicUpdate):
|
||||
clinic = self.db.query(Clinics).filter(Clinics.id == clinic_id).first()
|
||||
|
||||
if clinic is None:
|
||||
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)
|
||||
|
||||
for key, value in update_data.items():
|
||||
setattr(clinic, key, value)
|
||||
|
||||
self.db.add(clinic)
|
||||
self.db.commit()
|
||||
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):
|
||||
clinic = self.db.query(Clinics).filter(Clinics.id == clinic_id).first()
|
||||
@@ -94,4 +188,29 @@ class ClinicServices:
|
||||
if key:
|
||||
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
|
||||
|
||||
@@ -1,17 +1,74 @@
|
||||
from database import get_db
|
||||
from services.clinicDoctorsServices import ClinicDoctorsServices
|
||||
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:
|
||||
def __init__(self):
|
||||
self.db = next(get_db())
|
||||
self.clinicDoctorsServices = ClinicDoctorsServices()
|
||||
self.clinicServices = ClinicServices()
|
||||
|
||||
def get_dashboard_counts(self, isSuperAdmin:bool):
|
||||
|
||||
def get_dashboard_counts(self, isSuperAdmin: bool):
|
||||
if isSuperAdmin:
|
||||
clinicCounts = self.clinicServices.get_clinic_count()
|
||||
return clinicCounts
|
||||
else:
|
||||
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
|
||||
|
||||
@@ -11,10 +11,12 @@ from schemas.UpdateSchemas import UserUpdate
|
||||
from exceptions.unauthorized_exception import UnauthorizedException
|
||||
from interface.common_response import CommonResponse
|
||||
from exceptions.business_exception import BusinessValidationException
|
||||
from models import ClinicFileVerifications
|
||||
from utils.password_utils import hash_password
|
||||
from schemas.CreateSchemas import UserCreate
|
||||
from exceptions.resource_not_found_exception import ResourceNotFoundException
|
||||
from exceptions.db_exceptions import DBExceptionHandler
|
||||
from sqlalchemy.orm import joinedload
|
||||
|
||||
|
||||
class UserServices:
|
||||
@@ -98,7 +100,19 @@ class UserServices:
|
||||
|
||||
# Add clinic to database
|
||||
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
|
||||
self.db.commit()
|
||||
|
||||
@@ -114,7 +128,6 @@ class UserServices:
|
||||
def get_user(self, user_id) -> UserResponse:
|
||||
try:
|
||||
# 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()
|
||||
|
||||
if not user:
|
||||
|
||||
Reference in New Issue
Block a user