feat: endpoint for caddy
This commit is contained in:
+39
-23
@@ -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
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user