feat: freeze clinic api

This commit is contained in:
deepvasoya 2025-05-22 16:35:08 +05:30
parent b3a285293e
commit 8159d34c65
5 changed files with 54 additions and 56 deletions

View File

@ -14,9 +14,8 @@ router = APIRouter()
@router.put("/clinic/status") @router.put("/clinic/status")
def update_clinic_status(req:Request, data: ClinicStatusUpdate): def update_clinic_status(req:Request, data: ClinicStatusUpdate):
response = ClinicServices().update_clinic_status(req.state.user, data.clinic_id, data.status, data.documentStatus, data.rejection_reason) ClinicServices().update_clinic_status(req.state.user, data.clinic_id, data.status, data.documentStatus, data.rejection_reason)
return ApiResponse(data=response, message="Clinic status updated successfully") return ApiResponse(data="OK", message="Clinic status updated successfully")
@router.post("/user") @router.post("/user")
def create_user(req:Request, user_data: CreateSuperAdmin): def create_user(req:Request, user_data: CreateSuperAdmin):

View File

@ -1,3 +1,4 @@
from typing import Literal
from .BaseSchemas import * from .BaseSchemas import *
from enums.enums import ClinicStatus, Integration from enums.enums import ClinicStatus, Integration

View File

@ -155,6 +155,7 @@ class AuthService:
if user["userType"] != UserType.SUPER_ADMIN: if user["userType"] != UserType.SUPER_ADMIN:
raise UnauthorizedException("User is not authorized to perform this action") raise UnauthorizedException("User is not authorized to perform this action")
# password = "admin@123"
password = generate_secure_password() password = generate_secure_password()
hashed_password = hash_password(password) hashed_password = hash_password(password)
@ -185,7 +186,7 @@ class AuthService:
LOGIN_URL = self.url LOGIN_URL = self.url
# send email to user # send email to user
self.email_service.send_new_admin_email(data.email, password, LOGIN_URL) self.email_service.send_new_admin_email(data.username, data.email, password, LOGIN_URL)
return return

View File

@ -7,7 +7,7 @@ from exceptions import ResourceNotFoundException, ValidationException
from enums.enums import ClinicStatus, UserType from enums.enums import ClinicStatus, UserType
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 sqlalchemy import or_,func, case from sqlalchemy import or_,not_
from sqlalchemy import text from sqlalchemy import text
from services.s3Service import get_file_key, get_signed_url from services.s3Service import get_file_key, get_signed_url
@ -28,9 +28,9 @@ class ClinicServices:
clinics_query = self.db.query(Clinics) clinics_query = self.db.query(Clinics)
if filter_type == "UNREGISTERED": if filter_type == "UNREGISTERED":
clinics_query = clinics_query.filter(Clinics.status != ClinicStatus.ACTIVE) clinics_query = clinics_query.filter(not_(Clinics.status == ClinicStatus.ACTIVE),not_(Clinics.status == ClinicStatus.INACTIVE))
elif filter_type == "REGISTERED": elif filter_type == "REGISTERED":
clinics_query = clinics_query.filter(Clinics.status == ClinicStatus.ACTIVE) clinics_query = clinics_query.filter(or_(Clinics.status == ClinicStatus.ACTIVE,Clinics.status == ClinicStatus.INACTIVE))
if search: if search:
clinics_query = clinics_query.filter( clinics_query = clinics_query.filter(
@ -48,8 +48,8 @@ class ClinicServices:
count_query = text(""" count_query = text("""
SELECT SELECT
COUNT(*) as total, COUNT(*) as total,
COUNT(CASE WHEN status = 'ACTIVE' THEN 1 END) as active, COUNT(CASE WHEN status = 'ACTIVE' OR status = 'INACTIVE' THEN 1 END) as active,
COUNT(CASE WHEN status = 'REJECTED' OR status = 'UNDER_REVIEW' OR status = 'PAYMENT_DUE' OR status = 'REQUESTED_DOC' THEN 1 END) as rejected COUNT(CASE WHEN status != 'ACTIVE' AND status != 'INACTIVE' THEN 1 END) as rejected
FROM clinics FROM clinics
""") """)
@ -216,40 +216,40 @@ class ClinicServices:
if clinic.status == ClinicStatus.ACTIVE: if clinic.status == ClinicStatus.ACTIVE:
clinic_file_verification = self.db.query(ClinicFileVerifications).filter(ClinicFileVerifications.clinic_id == clinic_id).first() clinic_file_verification = self.db.query(ClinicFileVerifications).filter(ClinicFileVerifications.clinic_id == clinic_id).first()
clinic_file_verification.logo_is_verified = True clinic_file_verification.logo_is_verified = True
clinic_file_verification.abn_doc_is_verified = True clinic_file_verification.abn_doc_is_verified = True
clinic_file_verification.contract_doc_is_verified = True clinic_file_verification.contract_doc_is_verified = True
self.db.add(clinic_file_verification) self.db.add(clinic_file_verification)
self.db.commit() self.db.commit()
# send mail to user # send mail to user
self.email_service.send_apporve_clinic_email(clinic.email, clinic.name) self.email_service.send_apporve_clinic_email(clinic.email, clinic.name)
if clinic.status == ClinicStatus.REJECTED or clinic.status == ClinicStatus.UNDER_REVIEW: if clinic.status == ClinicStatus.REJECTED or clinic.status == ClinicStatus.UNDER_REVIEW:
clinic_file_verification = self.db.query(ClinicFileVerifications).filter(ClinicFileVerifications.clinic_id == clinic_id).first() clinic_file_verification = self.db.query(ClinicFileVerifications).filter(ClinicFileVerifications.clinic_id == clinic_id).first()
if documentStatus and "LOGO" in documentStatus: if documentStatus and "LOGO" in documentStatus:
clinic_file_verification.logo_is_verified = documentStatus.get("LOGO") clinic_file_verification.logo_is_verified = documentStatus.get("LOGO")
clinic_file_verification.rejection_reason = rejection_reason clinic_file_verification.rejection_reason = rejection_reason
if documentStatus and "ABN" in documentStatus: if documentStatus and "ABN" in documentStatus:
clinic_file_verification.abn_doc_is_verified = documentStatus.get("ABN") clinic_file_verification.abn_doc_is_verified = documentStatus.get("ABN")
clinic_file_verification.rejection_reason = rejection_reason clinic_file_verification.rejection_reason = rejection_reason
if documentStatus and "CONTRACT" in documentStatus: if documentStatus and "CONTRACT" in documentStatus:
clinic_file_verification.contract_doc_is_verified = documentStatus.get("CONTRACT") clinic_file_verification.contract_doc_is_verified = documentStatus.get("CONTRACT")
clinic_file_verification.rejection_reason = rejection_reason clinic_file_verification.rejection_reason = rejection_reason
self.db.add(clinic_file_verification) self.db.add(clinic_file_verification)
self.db.commit() self.db.commit()
# send mail to user # send mail to user
self.email_service.send_reject_clinic_email(clinic.email, clinic.name) self.email_service.send_reject_clinic_email(clinic.email, clinic.name)
# if rejected or under review then email to clinic creator # if rejected or under review then email to clinic creator

View File

@ -29,9 +29,9 @@ class EmailService:
<p>Thank you for using our service. To complete your authentication, please use the following one-time password (OTP):</p> <p>Thank you for using our service. To complete your authentication, please use the following one-time password (OTP):</p>
<p>OTP: {{otp}}</p> <p>OTP: {{otp}}</p>
<p>This OTP is valid for 15 minutes. Do not share this OTP with anyone for security reasons. If you did not request this OTP, please ignore this email.</p> <p>This OTP is valid for 15 minutes. Do not share this OTP with anyone for security reasons. If you did not request this OTP, please ignore this email.</p>
<p>Thank you,<br/>Team 24x7 AIHR</p> <p>Thank you,<br/>Team 24x7 AI Health Receptionist</p>
""", """,
"TextPart": "Dear User, Thank you for using our service. To complete your authentication, please use the following one-time password (OTP): OTP: {{otp}} This OTP is valid for 15 minutes. Do not share this OTP with anyone for security reasons. If you did not request this OTP, please ignore this email. Thank you, Team 24x7 AIHR" "TextPart": "Dear User, Thank you for using our service. To complete your authentication, please use the following one-time password (OTP): OTP: {{otp}} This OTP is valid for 15 minutes. Do not share this OTP with anyone for security reasons. If you did not request this OTP, please ignore this email. Thank you, Team 24x7 AI Health Receptionist"
} }
new_clinic_template = { new_clinic_template = {
@ -40,9 +40,9 @@ class EmailService:
"HtmlPart": """ "HtmlPart": """
<p>Dear Admin,</p> <p>Dear Admin,</p>
<p>A new clinic has been added to the system.</p> <p>A new clinic has been added to the system.</p>
<p>Thank you,<br/>Team 24x7 AIHR</p> <p>Thank you,<br/>Team 24x7 AI Health Receptionist</p>
""", """,
"TextPart": "Dear Admin, A new clinic has been added to the system. Thank you, Team 24x7 AIHR" "TextPart": "Dear Admin, A new clinic has been added to the system. Thank you, Team 24x7 AI Health Receptionist"
} }
reject_clinic_template = { reject_clinic_template = {
@ -51,9 +51,9 @@ class EmailService:
"HtmlPart": """ "HtmlPart": """
<p>Dear User,</p> <p>Dear User,</p>
<p>Your clinic {{name}} has been rejected.</p> <p>Your clinic {{name}} has been rejected.</p>
<p>Thank you,<br/>Team 24x7 AIHR</p> <p>Thank you,<br/>Team 24x7 AI Health Receptionist</p>
""", """,
"TextPart": "Dear User, Your clinic {{name}} has been rejected. Thank you, Team 24x7 AIHR" "TextPart": "Dear User, Your clinic {{name}} has been rejected. Thank you, Team 24x7 AI Health Receptionist"
} }
apporve_clinic_template = { apporve_clinic_template = {
@ -62,16 +62,18 @@ class EmailService:
"HtmlPart": """ "HtmlPart": """
<p>Dear User,</p> <p>Dear User,</p>
<p>Congratulations! Your clinic {{name}} has been approved.</p> <p>Congratulations! Your clinic {{name}} has been approved.</p>
<p>Thank you,<br/>Team 24x7 AIHR</p> <p>Thank you,<br/>Team 24x7 AI Health Receptionist</p>
""", """,
"TextPart": "Dear User, Congratulations! Your clinic {{name}} has been approved. Thank you, Team 24x7 AIHR" "TextPart": "Dear User, Congratulations! Your clinic {{name}} has been approved. Thank you, Team 24x7 AI Health Receptionist"
} }
new_admin_template = { new_admin_template = {
"TemplateName": "newAdmin", "TemplateName": "newAdmin",
"SubjectPart": "Login Credentials", "SubjectPart": "Login Credentials",
"HtmlPart": """ "HtmlPart": """
<p>Dear User,</p> <p>Dear {{username}},</p>
<p>You have been granted admin access to manage the 24x7 AI Health Receptionist System Admin Panel.</p>
<br />
<p>Your login credentials are:</p> <p>Your login credentials are:</p>
<div> <div>
<p>Email: {{email}}</p> <p>Email: {{email}}</p>
@ -81,9 +83,9 @@ class EmailService:
<p>Use the following link to login:</p> <p>Use the following link to login:</p>
<p>Login URL: {{login_url}}</p> <p>Login URL: {{login_url}}</p>
<br /> <br />
<p>Thank you,<br/>Team 24x7 AIHR</p> <p>Thank you,<br/>Team 24x7 AI Health Receptionist</p>
""", """,
"TextPart": "Dear User, Your login credentials are: Email: {{email}} Password: {{password}} Login URL: {{login_url}} Thank you, Team 24x7 AIHR" "TextPart": "Dear User, Your login credentials are: Email: {{email}} Password: {{password}} Login URL: {{login_url}} Thank you, Team 24x7 AI Health Receptionist System"
} }
reset_password_template = { reset_password_template = {
@ -94,9 +96,9 @@ class EmailService:
<p>You have requested to reset your password. Please use the following link to reset your password:</p> <p>You have requested to reset your password. Please use the following link to reset your password:</p>
<p>Reset Password URL: {{reset_password_url}}</p> <p>Reset Password URL: {{reset_password_url}}</p>
<br /> <br />
<p>Thank you,<br/>Team 24x7 AIHR</p> <p>Thank you,<br/>Team 24x7 AI Health Receptionist</p>
""", """,
"TextPart": "Dear User, You have requested to reset your password. Please use the following link to reset your password: Reset Password URL: {{reset_password_url}} Thank you, Team 24x7 AIHR" "TextPart": "Dear User, You have requested to reset your password. Please use the following link to reset your password: Reset Password URL: {{reset_password_url}} Thank you, Team 24x7 AI Health Receptionist"
} }
# self.client.create_template(Template=otp_template) # self.client.create_template(Template=otp_template)
@ -127,20 +129,15 @@ class EmailService:
return return
except Exception as e: except Exception as e:
logger.error(f"Error sending email to {to_address}: {str(e)}") logger.error(f"Error sending email to {to_address}: {str(e)}")
raise # raise TODO: un-comment when ready
def send_otp_email(self, email: str, otp: str) -> None: def send_otp_email(self, email: str, otp: str) -> None:
try: self.send_email(
"""Send OTP email""" template_name="sendOTP",
self.send_email( to_address=email,
template_name="sendOTP", template_data={"otp": otp, "email": email}
to_address=email, )
template_data={"otp": otp, "email": email} return
)
return
except Exception as e:
logger.error(f"Error sending OTP email to {email}: {str(e)}")
raise
def send_new_clinic_email(self, email: str, clinic_name: str): def send_new_clinic_email(self, email: str, clinic_name: str):
"""Send new clinic email""" """Send new clinic email"""
@ -169,12 +166,12 @@ class EmailService:
) )
return return
def send_new_admin_email(self, email: str, password:str, login_url:str): def send_new_admin_email(self, username: str, email: str, password:str, login_url:str):
"""Send new admin email""" """Send new admin email"""
self.send_email( self.send_email(
template_name="newAdmin", template_name="newAdmin",
to_address=email, to_address=email,
template_data={"email": email, "password": password, "login_url": login_url} template_data={"username": username, "email": email, "password": password, "login_url": login_url}
) )
return return