feat: endpoint for caddy

This commit is contained in:
2025-06-09 15:03:58 +05:30
parent 165385358f
commit db20c498c2
6 changed files with 95 additions and 266 deletions
+39 -23
View File
@@ -1,12 +1,12 @@
from database import get_db
from sqlalchemy.orm import Session, joinedload
from schemas.UpdateSchemas import ClinicStatusUpdate, ClinicUpdate
from schemas.UpdateSchemas import ClinicUpdate
from schemas.ResponseSchemas import Clinic, ClinicOfferResponse
from typing import List, Literal, Optional, Union
from typing import Literal, Optional, Union
from exceptions import ResourceNotFoundException, ValidationException
from enums.enums import ClinicStatus, UserType
from exceptions.unauthorized_exception import UnauthorizedException
from interface.common_response import CommonResponse
from interface.common_response import CommonResponse
from sqlalchemy import or_,not_
from sqlalchemy import text
@@ -18,6 +18,7 @@ from loguru import logger
from sqlalchemy import func
from exceptions.db_exceptions import DBExceptionHandler
class ClinicServices:
def __init__(self):
self.db: Session = next(get_db())
@@ -48,17 +49,17 @@ class ClinicServices:
)
clinics = clinics_query.offset(offset).limit(limit).all()
count_query = text("""
SELECT
SELECT
COUNT(*) as total,
COUNT(CASE WHEN status = 'ACTIVE' OR status = 'INACTIVE' OR status ='SUBSCRIPTION_ENDED' THEN 1 END) as active,
COUNT(CASE WHEN status != 'ACTIVE' AND status != 'INACTIVE' AND status != 'SUBSCRIPTION_ENDED' 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
@@ -100,7 +101,7 @@ class ClinicServices:
raise ResourceNotFoundException("Clinic not found")
clinic_response = Clinic(**clinic.__dict__.copy())
clinic_response.logo = await get_signed_url(clinic_response.logo) if clinic_response.logo else None
clinic_response.abn_doc = await get_signed_url(clinic_response.abn_doc) if clinic_response.abn_doc else None
clinic_response.contract_doc = await get_signed_url(clinic_response.contract_doc) if clinic_response.contract_doc else None
@@ -127,7 +128,7 @@ class ClinicServices:
finally:
self.db.close()
async def get_clinic_files(self, clinic_id: int):
try:
@@ -162,7 +163,7 @@ class ClinicServices:
clinic_data.logo = get_file_key(clinic_data.logo)
update_data = clinic_data.model_dump(exclude_unset=True)
for key, value in update_data.items():
setattr(clinic, key, value)
@@ -171,10 +172,10 @@ class ClinicServices:
self.db.refresh(clinic)
clinic_response = Clinic(**clinic.__dict__.copy())
# update clinic files
clinic_files = self.db.query(ClinicFileVerifications).filter(ClinicFileVerifications.clinic_id == clinic_id).first()
if clinic_data.abn_doc:
clinic_files.abn_doc_is_verified = None
if clinic_data.contract_doc:
@@ -207,10 +208,10 @@ class ClinicServices:
try:
# Get total count
totalClinics = self.db.query(Clinics).count()
# Get counts for specific statuses in a single query
status_counts = self.db.query(
Clinics.status,
Clinics.status,
func.count(Clinics.id).label('count')
).filter(
Clinics.status.in_([
@@ -222,7 +223,7 @@ class ClinicServices:
ClinicStatus.SUBSCRIPTION_ENDED
])
).group_by(Clinics.status).all()
# Initialize counts with 0
counts = {
"totalClinics": totalClinics,
@@ -231,7 +232,7 @@ class ClinicServices:
"totalRejectedClinics": 0,
"totalPaymentDueClinics": 0,
}
# Map status values to their respective count keys
status_to_key = {
ClinicStatus.ACTIVE: "totalActiveClinics",
@@ -239,7 +240,7 @@ class ClinicServices:
ClinicStatus.PAYMENT_DUE: "totalPaymentDueClinics",
ClinicStatus.REJECTED: "totalRejectedClinics"
}
# Update counts with actual values from the query
for status, count in status_counts:
key = status_to_key.get(status)
@@ -247,14 +248,14 @@ class ClinicServices:
counts[key] += count
else:
counts["totalActiveClinics"] += count
return counts
except Exception as e:
DBExceptionHandler.handle_exception(e, context="getting clinic count")
finally:
self.db.close()
async def update_clinic_status(self, user, clinic_id: int, status: ClinicStatus, documentStatus: Optional[dict] = None, rejection_reason: Optional[str] = None):
try:
if user["userType"] != UserType.SUPER_ADMIN:
@@ -324,7 +325,7 @@ class ClinicServices:
# self.db.commit()
pass
return
return
except Exception as e:
DBExceptionHandler.handle_exception(e, context="updating clinic status")
finally:
@@ -338,7 +339,7 @@ class ClinicServices:
DBExceptionHandler.handle_exception(e, context="getting clinic offer by clinic email")
finally:
self.db.close()
async def get_clinic_offers(self, user, limit:int, offset:int, search:str = ""):
try:
if user["userType"] != UserType.SUPER_ADMIN:
@@ -423,4 +424,19 @@ class ClinicServices:
except Exception as e:
DBExceptionHandler.handle_exception(e, context="deleting clinic offer")
finally:
self.db.close()
self.db.close()
async def is_valid_domain(self, domain:str):
subdomain = domain.split(".")[0]
# allow main domain, backend and admin domains
if(subdomain in ["toBeDomain", "backend", "admin"]):
return True
# check if any clinic has domain
clinic_domain = self.db.query(Clinic).filter(Clinic.domain == subdomain).first()
if clinic_domain:
return True
return False
+30 -40
View File
@@ -193,6 +193,7 @@ class StripeServices:
finally:
self.db.close()
# NOTE: in case when checkout session expired or not created
async def create_payment_session(self, user):
try:
if user["userType"] != UserType.CLINIC_ADMIN:
@@ -252,46 +253,34 @@ class StripeServices:
finally:
self.db.close()
async def create_checkout_session(self, user_id: int):
try:
checkout_session = await stripe.checkout.Session.create_async(
payment_method_types=["card"],
line_items=[
{
"price_data": {
"currency": "aud",
"product_data": {
"name": "Willio Voice Subscription",
},
"unit_amount": 5000,
},
"quantity": 1,
}
],
expand=["payment_intent"],
mode="payment",
payment_intent_data={"metadata": {"order_id": "1"}},
success_url=f"{self.redirect_url}auth/waiting",
cancel_url=f"{self.redirect_url}auth/waiting",
metadata={"user_id": user_id},
)
return checkout_session
except stripe.error.StripeError as e:
self.logger.error(f"Error creating checkout session: {e}")
raise
async def create_setup_fees(self, customer_id: str, amount: int):
try:
setup_intent = await stripe.InvoiceItem.create_async(
customer=customer_id,
amount=amount,
currency="aud",
description="Setup Fees",
)
return setup_intent
except stripe.error.StripeError as e:
self.logger.error(f"Error creating setup intent: {e}")
raise
# NOTE: This is not used
# async def create_checkout_session(self, user_id: int):
# try:
# checkout_session = await stripe.checkout.Session.create_async(
# payment_method_types=["card"],
# line_items=[
# {
# "price_data": {
# "currency": "aud",
# "product_data": {
# "name": "Willio Voice Subscription",
# },
# "unit_amount": 5000,
# },
# "quantity": 1,
# }
# ],
# expand=["payment_intent"],
# mode="payment",
# payment_intent_data={"metadata": {"order_id": "1"}},
# success_url=f"{self.redirect_url}auth/waiting",
# cancel_url=f"{self.redirect_url}auth/waiting",
# metadata={"user_id": user_id},
# )
# return checkout_session
# except stripe.error.StripeError as e:
# self.logger.error(f"Error creating checkout session: {e}")
# raise
async def create_subscription_checkout(
self, fees_to_be: dict, clinic_id: int, account_id: str, customer_id: str
@@ -313,6 +302,7 @@ class StripeServices:
), # Convert to cents
"recurring": {
"interval": "year",
"interval_count": 3, #NOTE: max 3 years supported by stripe
},
},
"quantity": 1,