feat: clinic bank details api
fix: relation betn stripe and user table
This commit is contained in:
parent
7f2f730426
commit
165385358f
|
|
@ -10,6 +10,7 @@ router = APIRouter()
|
||||||
|
|
||||||
@router.get("/")
|
@router.get("/")
|
||||||
async def get_clinic_doctors(
|
async def get_clinic_doctors(
|
||||||
|
req:Request,
|
||||||
limit:int= DEFAULT_LIMIT,
|
limit:int= DEFAULT_LIMIT,
|
||||||
page:int = DEFAULT_PAGE,
|
page:int = DEFAULT_PAGE,
|
||||||
search:str = "",
|
search:str = "",
|
||||||
|
|
@ -19,7 +20,7 @@ async def get_clinic_doctors(
|
||||||
if page < 1:
|
if page < 1:
|
||||||
page = 1
|
page = 1
|
||||||
offset = (page - 1) * limit
|
offset = (page - 1) * limit
|
||||||
clinic_doctors = await ClinicDoctorsServices().get_clinic_doctors(limit, offset, search, sort_by, sort_order)
|
clinic_doctors = await ClinicDoctorsServices().get_clinic_doctors(req.state.user, limit, offset, search, sort_by, sort_order)
|
||||||
return ApiResponse(data=clinic_doctors, message="Clinic doctors retrieved successfully")
|
return ApiResponse(data=clinic_doctors, message="Clinic doctors retrieved successfully")
|
||||||
|
|
||||||
@router.post("/")
|
@router.post("/")
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ router = APIRouter()
|
||||||
|
|
||||||
@router.get("/")
|
@router.get("/")
|
||||||
async def get_clinic_doctor_status_count(req:Request):
|
async def get_clinic_doctor_status_count(req:Request):
|
||||||
counts = await DashboardService().get_dashboard_counts(isSuperAdmin=req.state.user["userType"] == UserType.SUPER_ADMIN)
|
counts = await DashboardService().get_dashboard_counts(req.state.user)
|
||||||
return ApiResponse(data=counts, message="Counts fetched successfully")
|
return ApiResponse(data=counts, message="Counts fetched successfully")
|
||||||
|
|
||||||
@router.post("/signup-pricing-master")
|
@router.post("/signup-pricing-master")
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,10 @@ stripe_service = StripeServices()
|
||||||
# customer_id="cus_SNn49FDltUcSLP"
|
# customer_id="cus_SNn49FDltUcSLP"
|
||||||
# )
|
# )
|
||||||
|
|
||||||
|
@router.get("/create-stripe-account-link", dependencies=[Depends(auth_required)])
|
||||||
|
async def create_stripe_account_link(req:Request):
|
||||||
|
link = await stripe_service.create_stripe_account_link(req.state.user)
|
||||||
|
return ApiResponse(data=link, message="Stripe account link created successfully")
|
||||||
|
|
||||||
@router.get("/get-invoice", dependencies=[Depends(auth_required)])
|
@router.get("/get-invoice", dependencies=[Depends(auth_required)])
|
||||||
async def get_invoice(req:Request):
|
async def get_invoice(req:Request):
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
"""updated_stripeuser
|
||||||
|
|
||||||
|
Revision ID: e50edac1c8f0
|
||||||
|
Revises: 8d19e726b997
|
||||||
|
Create Date: 2025-06-05 18:22:38.502127
|
||||||
|
|
||||||
|
"""
|
||||||
|
from typing import Sequence, Union
|
||||||
|
|
||||||
|
from alembic import op
|
||||||
|
import sqlalchemy as sa
|
||||||
|
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision: str = 'e50edac1c8f0'
|
||||||
|
down_revision: Union[str, None] = '8d19e726b997'
|
||||||
|
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('stripe_users', sa.Column('clinic_id', sa.Integer(), nullable=True))
|
||||||
|
op.drop_constraint('stripe_users_user_id_key', 'stripe_users', type_='unique')
|
||||||
|
op.drop_constraint('stripe_users_user_id_fkey', 'stripe_users', type_='foreignkey')
|
||||||
|
op.create_foreign_key(None, 'stripe_users', 'clinics', ['clinic_id'], ['id'])
|
||||||
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade() -> None:
|
||||||
|
"""Downgrade schema."""
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
op.drop_constraint(None, 'stripe_users', type_='foreignkey')
|
||||||
|
op.create_foreign_key('stripe_users_user_id_fkey', 'stripe_users', 'users', ['user_id'], ['id'])
|
||||||
|
op.create_unique_constraint('stripe_users_user_id_key', 'stripe_users', ['user_id'])
|
||||||
|
op.drop_column('stripe_users', 'clinic_id')
|
||||||
|
# ### end Alembic commands ###
|
||||||
|
|
@ -45,4 +45,7 @@ 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")
|
clinic_file_verifications = relationship("ClinicFileVerifications", back_populates="clinic")
|
||||||
|
|
||||||
|
# Stripe relationships
|
||||||
|
stripe_user = relationship("StripeUsers", back_populates="clinic")
|
||||||
|
|
@ -6,8 +6,10 @@ from sqlalchemy.orm import relationship
|
||||||
class StripeUsers(Base, CustomBase):
|
class StripeUsers(Base, CustomBase):
|
||||||
__tablename__ = "stripe_users"
|
__tablename__ = "stripe_users"
|
||||||
id = Column(Integer, primary_key=True, index=True)
|
id = Column(Integer, primary_key=True, index=True)
|
||||||
user_id = Column(Integer, ForeignKey('users.id'), nullable=False, unique=True)
|
user_id = Column(Integer, nullable=True)
|
||||||
|
clinic_id = Column(Integer, ForeignKey('clinics.id'), nullable=True)
|
||||||
customer_id = Column(String)
|
customer_id = Column(String)
|
||||||
account_id = Column(String)
|
account_id = Column(String)
|
||||||
|
|
||||||
user = relationship("Users", back_populates="stripe_user")
|
|
||||||
|
clinic = relationship("Clinics", back_populates="stripe_user")
|
||||||
|
|
@ -27,5 +27,4 @@ class Users(Base, CustomBase):
|
||||||
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")
|
clinic_file_verifications = relationship("ClinicFileVerifications", back_populates="last_changed_by_user")
|
||||||
|
|
||||||
# Stripe relationships
|
# No longer have Stripe relationships
|
||||||
stripe_user = relationship("StripeUsers", back_populates="user")
|
|
||||||
|
|
@ -139,3 +139,8 @@ class ClinicOffersBase(BaseModel):
|
||||||
setup_fees_waived: bool
|
setup_fees_waived: bool
|
||||||
special_offer_for_month: str
|
special_offer_for_month: str
|
||||||
|
|
||||||
|
|
||||||
|
class StripeUserBase(BaseModel):
|
||||||
|
account_id: str
|
||||||
|
customer_id: str
|
||||||
|
user_id: int
|
||||||
|
|
@ -23,7 +23,7 @@ class ClinicDoctorResponse(ClinicDoctorBase):
|
||||||
update_time: datetime
|
update_time: datetime
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
orm_mode = True
|
from_attributes = True
|
||||||
|
|
||||||
|
|
||||||
class SignupPricingMasterResponse(SignupPricingMasterBase):
|
class SignupPricingMasterResponse(SignupPricingMasterBase):
|
||||||
|
|
@ -32,7 +32,7 @@ class SignupPricingMasterResponse(SignupPricingMasterBase):
|
||||||
update_time: datetime
|
update_time: datetime
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
orm_mode = True
|
from_attributes = True
|
||||||
|
|
||||||
|
|
||||||
class UserResponse(UserBase):
|
class UserResponse(UserBase):
|
||||||
|
|
@ -53,7 +53,7 @@ class Doctor(DoctorBase):
|
||||||
update_time: datetime
|
update_time: datetime
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
orm_mode = True
|
from_attributes = True
|
||||||
|
|
||||||
|
|
||||||
class Patient(PatientBase):
|
class Patient(PatientBase):
|
||||||
|
|
@ -62,7 +62,7 @@ class Patient(PatientBase):
|
||||||
update_time: datetime
|
update_time: datetime
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
orm_mode = True
|
from_attributes = True
|
||||||
|
|
||||||
|
|
||||||
class AppointmentSchema(AppointmentBase):
|
class AppointmentSchema(AppointmentBase):
|
||||||
|
|
@ -71,7 +71,7 @@ class AppointmentSchema(AppointmentBase):
|
||||||
update_time: datetime
|
update_time: datetime
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
orm_mode = True
|
from_attributes = True
|
||||||
|
|
||||||
|
|
||||||
class Calendar(CalendarBase):
|
class Calendar(CalendarBase):
|
||||||
|
|
@ -80,7 +80,7 @@ class Calendar(CalendarBase):
|
||||||
update_time: datetime
|
update_time: datetime
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
orm_mode = True
|
from_attributes = True
|
||||||
|
|
||||||
|
|
||||||
# custom schema for response
|
# custom schema for response
|
||||||
|
|
@ -88,7 +88,7 @@ class CalendarTimeSchema(BaseModel):
|
||||||
time: str
|
time: str
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
orm_mode = True
|
from_attributes = True
|
||||||
|
|
||||||
|
|
||||||
class ClinicSchema(BaseModel):
|
class ClinicSchema(BaseModel):
|
||||||
|
|
@ -99,7 +99,7 @@ class ClinicSchema(BaseModel):
|
||||||
email: str
|
email: str
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
orm_mode = True
|
from_attributes = True
|
||||||
|
|
||||||
|
|
||||||
# Detailed response schemas with nested relationships
|
# Detailed response schemas with nested relationships
|
||||||
|
|
@ -133,7 +133,7 @@ class AppointmentDetailed(AppointmentSchema):
|
||||||
address: str
|
address: str
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
orm_mode = True
|
from_attributes = True
|
||||||
|
|
||||||
class Patient(BaseModel):
|
class Patient(BaseModel):
|
||||||
id: int
|
id: int
|
||||||
|
|
@ -145,7 +145,7 @@ class AppointmentDetailed(AppointmentSchema):
|
||||||
dob: str
|
dob: str
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
orm_mode = True
|
from_attributes = True
|
||||||
|
|
||||||
doctor: Doctor
|
doctor: Doctor
|
||||||
patient: Patient
|
patient: Patient
|
||||||
|
|
@ -157,7 +157,7 @@ class CallTranscriptsResponse(CallTranscriptsBase):
|
||||||
update_time: datetime
|
update_time: datetime
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
orm_mode = True
|
from_attributes = True
|
||||||
|
|
||||||
|
|
||||||
class NotificationResponse(NotificationBase):
|
class NotificationResponse(NotificationBase):
|
||||||
|
|
@ -166,7 +166,7 @@ class NotificationResponse(NotificationBase):
|
||||||
update_time: datetime
|
update_time: datetime
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
orm_mode = True
|
from_attributes = True
|
||||||
|
|
||||||
|
|
||||||
class MasterAppointmentTypeResponse(MasterAppointmentTypeBase):
|
class MasterAppointmentTypeResponse(MasterAppointmentTypeBase):
|
||||||
|
|
@ -175,7 +175,7 @@ class MasterAppointmentTypeResponse(MasterAppointmentTypeBase):
|
||||||
update_time: datetime
|
update_time: datetime
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
orm_mode = True
|
from_attributes = True
|
||||||
|
|
||||||
|
|
||||||
class ClinicDoctorResponse(ClinicDoctorBase):
|
class ClinicDoctorResponse(ClinicDoctorBase):
|
||||||
|
|
@ -185,7 +185,6 @@ class ClinicDoctorResponse(ClinicDoctorBase):
|
||||||
appointmentTypes: Optional[List[MasterAppointmentTypeResponse]] = []
|
appointmentTypes: Optional[List[MasterAppointmentTypeResponse]] = []
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
orm_mode = True
|
|
||||||
from_attributes = True
|
from_attributes = True
|
||||||
allow_population_by_field_name = True
|
allow_population_by_field_name = True
|
||||||
|
|
||||||
|
|
@ -196,4 +195,14 @@ class ClinicOfferResponse(ClinicOffersBase):
|
||||||
update_time: datetime
|
update_time: datetime
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
orm_mode = True
|
from_attributes = True
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class StripeUserReponse(StripeUserBase):
|
||||||
|
id: int
|
||||||
|
create_time: datetime
|
||||||
|
update_time: datetime
|
||||||
|
|
||||||
|
class Config:
|
||||||
|
from_attributes = True
|
||||||
|
|
@ -3,14 +3,13 @@ from schemas.CreateSchemas import ClinicDoctorCreate
|
||||||
from schemas.UpdateSchemas import ClinicDoctorUpdate
|
from schemas.UpdateSchemas import ClinicDoctorUpdate
|
||||||
from schemas.ResponseSchemas import ClinicDoctorResponse, MasterAppointmentTypeResponse
|
from schemas.ResponseSchemas import ClinicDoctorResponse, MasterAppointmentTypeResponse
|
||||||
from database import get_db
|
from database import get_db
|
||||||
from models import ClinicDoctors
|
|
||||||
from sqlalchemy.orm import Session, joinedload, selectinload
|
from sqlalchemy.orm import Session, joinedload, selectinload
|
||||||
from services.clinicServices import ClinicServices
|
from services.clinicServices import ClinicServices
|
||||||
from exceptions import ResourceNotFoundException
|
from exceptions import ResourceNotFoundException
|
||||||
from interface.common_response import CommonResponse
|
from interface.common_response import CommonResponse
|
||||||
from sqlalchemy import func, or_, cast, String
|
from sqlalchemy import func, or_, cast, String
|
||||||
from enums.enums import ClinicDoctorStatus, UserType
|
from enums.enums import ClinicDoctorStatus, UserType
|
||||||
from models import MasterAppointmentTypes, AppointmentRelations
|
from models import MasterAppointmentTypes, AppointmentRelations, Users, ClinicDoctors
|
||||||
from utils.constants import DEFAULT_ORDER, DEFAULT_ORDER_BY
|
from utils.constants import DEFAULT_ORDER, DEFAULT_ORDER_BY
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -174,13 +173,14 @@ class ClinicDoctorsServices:
|
||||||
finally:
|
finally:
|
||||||
self.db.close()
|
self.db.close()
|
||||||
|
|
||||||
async def get_doctor_status_count(self):
|
async def get_doctor_status_count(self, clinic_id:int):
|
||||||
try:
|
try:
|
||||||
# Query to count doctors by status
|
# Query to count doctors by status
|
||||||
status_counts = (
|
status_counts = (
|
||||||
self.db.query(
|
self.db.query(
|
||||||
ClinicDoctors.status, func.count(ClinicDoctors.id).label("count")
|
ClinicDoctors.status, func.count(ClinicDoctors.id).label("count")
|
||||||
)
|
)
|
||||||
|
.filter(ClinicDoctors.clinic_id == clinic_id)
|
||||||
.group_by(ClinicDoctors.status)
|
.group_by(ClinicDoctors.status)
|
||||||
.all()
|
.all()
|
||||||
)
|
)
|
||||||
|
|
@ -198,17 +198,18 @@ class ClinicDoctorsServices:
|
||||||
finally:
|
finally:
|
||||||
self.db.close()
|
self.db.close()
|
||||||
|
|
||||||
async def get_clinic_doctors(self, limit: int, offset: int, search: str = "", sort_by: str = DEFAULT_ORDER, sort_order: str = DEFAULT_ORDER_BY):
|
async def get_clinic_doctors(self,user, limit: int, offset: int, search: str = "", sort_by: str = DEFAULT_ORDER, sort_order: str = DEFAULT_ORDER_BY):
|
||||||
try:
|
try:
|
||||||
clinic_doctors_query = (
|
clinic_doctors_query = (
|
||||||
self.db.query(ClinicDoctors)
|
self.db.query(ClinicDoctors)
|
||||||
|
.filter(ClinicDoctors.clinic_id == user["created_clinics"][0]["id"])
|
||||||
.options(
|
.options(
|
||||||
selectinload(ClinicDoctors.appointmentRelations)
|
selectinload(ClinicDoctors.appointmentRelations)
|
||||||
.selectinload(AppointmentRelations.masterAppointmentTypes)
|
.selectinload(AppointmentRelations.masterAppointmentTypes)
|
||||||
)
|
)
|
||||||
.order_by(
|
.order_by(
|
||||||
getattr(ClinicDoctors, sort_by).desc()
|
getattr(ClinicDoctors, sort_by).desc()
|
||||||
if sort_order == "desc"
|
if sort_order == "desc"
|
||||||
else getattr(ClinicDoctors, sort_by).asc()
|
else getattr(ClinicDoctors, sort_by).asc()
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
@ -230,7 +231,7 @@ class ClinicDoctorsServices:
|
||||||
total = clinic_doctors_query.count()
|
total = clinic_doctors_query.count()
|
||||||
|
|
||||||
clinic_doctors = clinic_doctors_query.limit(limit).offset(offset).all()
|
clinic_doctors = clinic_doctors_query.limit(limit).offset(offset).all()
|
||||||
|
|
||||||
# Build response data manually to include appointment types
|
# Build response data manually to include appointment types
|
||||||
response_data = []
|
response_data = []
|
||||||
for clinic_doctor in clinic_doctors:
|
for clinic_doctor in clinic_doctors:
|
||||||
|
|
@ -246,7 +247,7 @@ class ClinicDoctorsServices:
|
||||||
update_time=relation.masterAppointmentTypes.update_time
|
update_time=relation.masterAppointmentTypes.update_time
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
# Create the clinic doctor response
|
# Create the clinic doctor response
|
||||||
clinic_doctor_data = ClinicDoctorResponse(
|
clinic_doctor_data = ClinicDoctorResponse(
|
||||||
id=clinic_doctor.id,
|
id=clinic_doctor.id,
|
||||||
|
|
@ -258,7 +259,7 @@ class ClinicDoctorsServices:
|
||||||
appointmentTypes=appointment_types
|
appointmentTypes=appointment_types
|
||||||
)
|
)
|
||||||
response_data.append(clinic_doctor_data)
|
response_data.append(clinic_doctor_data)
|
||||||
|
|
||||||
response = CommonResponse(
|
response = CommonResponse(
|
||||||
data=response_data,
|
data=response_data,
|
||||||
total=total,
|
total=total,
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,8 @@ from exceptions import UnauthorizedException
|
||||||
from enums.enums import UserType
|
from enums.enums import UserType
|
||||||
from exceptions import ResourceNotFoundException
|
from exceptions import ResourceNotFoundException
|
||||||
from loguru import logger
|
from loguru import logger
|
||||||
|
|
||||||
|
from models import Users
|
||||||
class DashboardService:
|
class DashboardService:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.db = next(get_db())
|
self.db = next(get_db())
|
||||||
|
|
@ -15,13 +17,17 @@ class DashboardService:
|
||||||
self.clinicServices = ClinicServices()
|
self.clinicServices = ClinicServices()
|
||||||
self.logger = logger
|
self.logger = logger
|
||||||
|
|
||||||
async def get_dashboard_counts(self, isSuperAdmin: bool):
|
async def get_dashboard_counts(self, user):
|
||||||
if isSuperAdmin:
|
try:
|
||||||
clinicCounts = await self.clinicServices.get_clinic_count()
|
if user["userType"] == UserType.SUPER_ADMIN:
|
||||||
return clinicCounts
|
clinicCounts = await self.clinicServices.get_clinic_count()
|
||||||
else:
|
return clinicCounts
|
||||||
clinicDoctorsCount = await self.clinicDoctorsServices.get_doctor_status_count()
|
else:
|
||||||
return clinicDoctorsCount
|
clinicDoctorsCount = await self.clinicDoctorsServices.get_doctor_status_count(user["created_clinics"][0]["id"])
|
||||||
|
return clinicDoctorsCount
|
||||||
|
except Exception as e:
|
||||||
|
self.logger.error("Error getting dashboard counts: ", e)
|
||||||
|
raise e
|
||||||
|
|
||||||
async def update_signup_pricing_master(
|
async def update_signup_pricing_master(
|
||||||
self, user, pricing_data: SignupPricingMasterBase
|
self, user, pricing_data: SignupPricingMasterBase
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@ import os
|
||||||
import dotenv
|
import dotenv
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
dotenv.load_dotenv()
|
dotenv.load_dotenv()
|
||||||
|
|
||||||
from models import ClinicOffers, StripeUsers
|
from models import ClinicOffers, StripeUsers
|
||||||
|
|
@ -11,12 +10,13 @@ from services.dashboardService import DashboardService
|
||||||
from exceptions.validation_exception import ValidationException
|
from exceptions.validation_exception import ValidationException
|
||||||
from exceptions.resource_not_found_exception import ResourceNotFoundException
|
from exceptions.resource_not_found_exception import ResourceNotFoundException
|
||||||
from exceptions.unauthorized_exception import UnauthorizedException
|
from exceptions.unauthorized_exception import UnauthorizedException
|
||||||
from models import Clinics,PaymentSessions, Subscriptions
|
from models import Clinics, PaymentSessions, Subscriptions
|
||||||
import uuid
|
import uuid
|
||||||
from fastapi import Request
|
from fastapi import Request
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from models import PaymentLogs
|
from models import PaymentLogs
|
||||||
from enums.enums import ClinicStatus, UserType
|
from enums.enums import ClinicStatus, UserType
|
||||||
|
from schemas.ResponseSchemas import StripeUserReponse
|
||||||
|
|
||||||
from database import get_db
|
from database import get_db
|
||||||
from sqlalchemy.orm import Session
|
from sqlalchemy.orm import Session
|
||||||
|
|
@ -75,28 +75,110 @@ class StripeServices:
|
||||||
self.logger.error(f"Error deleting account: {e}")
|
self.logger.error(f"Error deleting account: {e}")
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
async def get_stripe_data(self, clinic_id: int):
|
||||||
|
try:
|
||||||
|
user = (
|
||||||
|
self.db.query(StripeUsers)
|
||||||
|
.filter(StripeUsers.clinic_id == clinic_id)
|
||||||
|
.first()
|
||||||
|
)
|
||||||
|
|
||||||
|
if not user:
|
||||||
|
self.logger.error(f"User not found!")
|
||||||
|
raise ResourceNotFoundException("User not found!")
|
||||||
|
|
||||||
|
return StripeUserReponse.model_validate(user).model_dump()
|
||||||
|
except Exception as e:
|
||||||
|
self.logger.error(f"Error retrieving account data: {e}")
|
||||||
|
raise
|
||||||
|
finally:
|
||||||
|
self.db.close()
|
||||||
|
|
||||||
|
async def create_stripe_account_link(self, user):
|
||||||
|
try:
|
||||||
|
stripe_account = await self.get_stripe_data(user["created_clinics"][0]["id"])
|
||||||
|
|
||||||
|
if not stripe_account:
|
||||||
|
self.logger.error("Stripe account not found!")
|
||||||
|
raise ResourceNotFoundException("Stripe account not found!")
|
||||||
|
|
||||||
|
# Pass the account_id as a string, not as a dictionary
|
||||||
|
data = await stripe.AccountLink.create_async(
|
||||||
|
account=stripe_account["account_id"],
|
||||||
|
refresh_url=self.redirect_url,
|
||||||
|
return_url=self.redirect_url,
|
||||||
|
type="account_onboarding",
|
||||||
|
)
|
||||||
|
|
||||||
|
return data.url
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
self.logger.error(f"Error creating stripe account link: {e}")
|
||||||
|
raise
|
||||||
|
|
||||||
|
async def check_account_capabilities(self, user):
|
||||||
|
try:
|
||||||
|
stripe_account = await self.get_stripe_data(user["created_clinics"][0]["id"])
|
||||||
|
|
||||||
|
if not stripe_account:
|
||||||
|
self.logger.error("Stripe account not found!")
|
||||||
|
raise ResourceNotFoundException("Stripe account not found!")
|
||||||
|
|
||||||
|
data = await stripe.Account.retrieve_async(stripe_account["account_id"])
|
||||||
|
|
||||||
|
return {
|
||||||
|
"capabilities": data.capabilities,
|
||||||
|
"charges_enabled": data.charges_enabled,
|
||||||
|
"requirements": data.requirements.currently_due,
|
||||||
|
"error": data.requirements.errors,
|
||||||
|
}
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
self.logger.error(f"Error checking stripe account capabilities: {e}")
|
||||||
|
raise
|
||||||
|
finally:
|
||||||
|
self.db.close()
|
||||||
|
|
||||||
async def get_invoice(self, user):
|
async def get_invoice(self, user):
|
||||||
try:
|
try:
|
||||||
|
|
||||||
if user["userType"] != UserType.CLINIC_ADMIN:
|
if user["userType"] != UserType.CLINIC_ADMIN:
|
||||||
raise UnauthorizedException("User is not authorized to perform this action")
|
raise UnauthorizedException(
|
||||||
|
"User is not authorized to perform this action"
|
||||||
|
)
|
||||||
|
|
||||||
clinic = self.db.query(Clinics).filter(Clinics.creator_id == user["id"]).first()
|
clinic = (
|
||||||
|
self.db.query(Clinics).filter(Clinics.creator_id == user["id"]).first()
|
||||||
|
)
|
||||||
|
|
||||||
if not clinic:
|
if not clinic:
|
||||||
raise ResourceNotFoundException("Clinic not found!")
|
raise ResourceNotFoundException("Clinic not found!")
|
||||||
|
|
||||||
customer = self.db.query(StripeUsers).filter(StripeUsers.user_id == user["id"]).first()
|
customer = (
|
||||||
|
self.db.query(StripeUsers)
|
||||||
|
.filter(StripeUsers.user_id == user["id"])
|
||||||
|
.first()
|
||||||
|
)
|
||||||
|
|
||||||
if not customer:
|
if not customer:
|
||||||
raise ResourceNotFoundException("Customer not found!")
|
raise ResourceNotFoundException("Customer not found!")
|
||||||
|
|
||||||
subscription = self.db.query(Subscriptions).filter(Subscriptions.clinic_id == clinic.id, Subscriptions.customer_id == customer.customer_id, Subscriptions.status == "active").first()
|
subscription = (
|
||||||
|
self.db.query(Subscriptions)
|
||||||
|
.filter(
|
||||||
|
Subscriptions.clinic_id == clinic.id,
|
||||||
|
Subscriptions.customer_id == customer.customer_id,
|
||||||
|
Subscriptions.status == "active",
|
||||||
|
)
|
||||||
|
.first()
|
||||||
|
)
|
||||||
|
|
||||||
if not subscription:
|
if not subscription:
|
||||||
raise ResourceNotFoundException("Subscription not found!")
|
raise ResourceNotFoundException("Subscription not found!")
|
||||||
|
|
||||||
stripe_subscription = await stripe.Subscription.retrieve_async(subscription.subscription_id)
|
stripe_subscription = await stripe.Subscription.retrieve_async(
|
||||||
|
subscription.subscription_id
|
||||||
|
)
|
||||||
|
|
||||||
invoice = await stripe.Invoice.retrieve_async(
|
invoice = await stripe.Invoice.retrieve_async(
|
||||||
stripe_subscription["latest_invoice"]
|
stripe_subscription["latest_invoice"]
|
||||||
|
|
@ -114,36 +196,54 @@ class StripeServices:
|
||||||
async def create_payment_session(self, user):
|
async def create_payment_session(self, user):
|
||||||
try:
|
try:
|
||||||
if user["userType"] != UserType.CLINIC_ADMIN:
|
if user["userType"] != UserType.CLINIC_ADMIN:
|
||||||
raise UnauthorizedException("User is not authorized to perform this action")
|
raise UnauthorizedException(
|
||||||
|
"User is not authorized to perform this action"
|
||||||
|
)
|
||||||
|
|
||||||
clinic = user["created_clinics"][0]
|
clinic = user["created_clinics"][0]
|
||||||
|
|
||||||
if clinic["status"] != ClinicStatus.PAYMENT_DUE:
|
if clinic["status"] != ClinicStatus.PAYMENT_DUE:
|
||||||
raise ValidationException("Clinic is not due for payment")
|
raise ValidationException("Clinic is not due for payment")
|
||||||
|
|
||||||
customer = self.db.query(StripeUsers).filter(StripeUsers.user_id == user['id']).first()
|
customer = (
|
||||||
|
self.db.query(StripeUsers)
|
||||||
|
.filter(StripeUsers.user_id == user["id"])
|
||||||
|
.first()
|
||||||
|
)
|
||||||
|
|
||||||
if not customer:
|
if not customer:
|
||||||
raise ResourceNotFoundException("Customer not found")
|
raise ResourceNotFoundException("Customer not found")
|
||||||
|
|
||||||
clinic_offers = self.db.query(ClinicOffers).filter(ClinicOffers.clinic_email == clinic["email"]).first()
|
clinic_offers = (
|
||||||
|
self.db.query(ClinicOffers)
|
||||||
|
.filter(ClinicOffers.clinic_email == clinic["email"])
|
||||||
|
.first()
|
||||||
|
)
|
||||||
|
|
||||||
signup_pricing= await self.dashboard_service.get_signup_pricing_master()
|
signup_pricing = await self.dashboard_service.get_signup_pricing_master()
|
||||||
|
|
||||||
fees_to_be = {
|
fees_to_be = {
|
||||||
"setup_fees": signup_pricing.setup_fees,
|
"setup_fees": signup_pricing.setup_fees,
|
||||||
"subscription_fees": signup_pricing.subscription_fees,
|
"subscription_fees": signup_pricing.subscription_fees,
|
||||||
"per_call_charges": signup_pricing.per_call_charges,
|
"per_call_charges": signup_pricing.per_call_charges,
|
||||||
"total": signup_pricing.setup_fees + signup_pricing.subscription_fees + signup_pricing.per_call_charges
|
"total": signup_pricing.setup_fees
|
||||||
|
+ signup_pricing.subscription_fees
|
||||||
|
+ signup_pricing.per_call_charges,
|
||||||
}
|
}
|
||||||
|
|
||||||
if clinic_offers:
|
if clinic_offers:
|
||||||
fees_to_be["setup_fees"] = clinic_offers.setup_fees
|
fees_to_be["setup_fees"] = clinic_offers.setup_fees
|
||||||
fees_to_be["per_call_charges"] = clinic_offers.per_call_charges
|
fees_to_be["per_call_charges"] = clinic_offers.per_call_charges
|
||||||
fees_to_be["total"] = clinic_offers.setup_fees + fees_to_be["subscription_fees"] + clinic_offers.per_call_charges
|
fees_to_be["total"] = (
|
||||||
|
clinic_offers.setup_fees
|
||||||
payment_link = await self.create_subscription_checkout(fees_to_be, clinic["id"], customer.account_id, customer.customer_id)
|
+ fees_to_be["subscription_fees"]
|
||||||
|
+ clinic_offers.per_call_charges
|
||||||
|
)
|
||||||
|
|
||||||
|
payment_link = await self.create_subscription_checkout(
|
||||||
|
fees_to_be, clinic["id"], customer.account_id, customer.customer_id
|
||||||
|
)
|
||||||
|
|
||||||
return payment_link.url
|
return payment_link.url
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|
@ -193,67 +293,79 @@ class StripeServices:
|
||||||
self.logger.error(f"Error creating setup intent: {e}")
|
self.logger.error(f"Error creating setup intent: {e}")
|
||||||
raise
|
raise
|
||||||
|
|
||||||
async def create_subscription_checkout(self, fees_to_be: dict, clinic_id: int, account_id: str, customer_id: str):
|
async def create_subscription_checkout(
|
||||||
|
self, fees_to_be: dict, clinic_id: int, account_id: str, customer_id: str
|
||||||
|
):
|
||||||
try:
|
try:
|
||||||
|
|
||||||
unique_id = str(uuid.uuid4())
|
unique_id = str(uuid.uuid4())
|
||||||
unique_clinic_id = f"clinic_{clinic_id}_{unique_id}"
|
unique_clinic_id = f"clinic_{clinic_id}_{unique_id}"
|
||||||
|
|
||||||
line_items = [{
|
line_items = [
|
||||||
'price_data': {
|
{
|
||||||
'currency': 'aud',
|
"price_data": {
|
||||||
'product_data': {
|
"currency": "aud",
|
||||||
'name': 'Monthly Subscription',
|
"product_data": {
|
||||||
|
"name": "Monthly Subscription",
|
||||||
|
},
|
||||||
|
"unit_amount": int(
|
||||||
|
fees_to_be["subscription_fees"] * 100
|
||||||
|
), # Convert to cents
|
||||||
|
"recurring": {
|
||||||
|
"interval": "year",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
'unit_amount': int(fees_to_be["subscription_fees"] * 100), # Convert to cents
|
"quantity": 1,
|
||||||
'recurring': {
|
}
|
||||||
'interval': 'year',
|
]
|
||||||
},
|
|
||||||
},
|
|
||||||
'quantity': 1,
|
|
||||||
}]
|
|
||||||
|
|
||||||
line_items.append({
|
line_items.append(
|
||||||
'price_data': {
|
{
|
||||||
'currency': 'aud',
|
"price_data": {
|
||||||
'product_data': {
|
"currency": "aud",
|
||||||
'name': 'Per Call',
|
"product_data": {
|
||||||
|
"name": "Per Call",
|
||||||
|
},
|
||||||
|
"unit_amount": int(
|
||||||
|
fees_to_be["per_call_charges"] * 100
|
||||||
|
), # Convert to cents
|
||||||
},
|
},
|
||||||
'unit_amount': int(fees_to_be["per_call_charges"] * 100), # Convert to cents
|
"quantity": 1,
|
||||||
},
|
}
|
||||||
'quantity': 1,
|
)
|
||||||
})
|
|
||||||
|
|
||||||
line_items.append({
|
line_items.append(
|
||||||
'price_data': {
|
{
|
||||||
'currency': 'aud',
|
"price_data": {
|
||||||
'product_data': {
|
"currency": "aud",
|
||||||
'name': 'Setup Fee',
|
"product_data": {
|
||||||
|
"name": "Setup Fee",
|
||||||
|
},
|
||||||
|
"unit_amount": int(
|
||||||
|
fees_to_be["setup_fees"] * 100
|
||||||
|
), # Convert to cents
|
||||||
},
|
},
|
||||||
'unit_amount': int(fees_to_be["setup_fees"] * 100), # Convert to cents
|
"quantity": 1,
|
||||||
},
|
}
|
||||||
'quantity': 1,
|
)
|
||||||
})
|
|
||||||
|
|
||||||
metadata = {
|
metadata = {
|
||||||
"clinic_id": clinic_id,
|
"clinic_id": clinic_id,
|
||||||
"unique_clinic_id": unique_clinic_id,
|
"unique_clinic_id": unique_clinic_id,
|
||||||
"account_id": account_id,
|
"account_id": account_id,
|
||||||
"customer_id": customer_id,
|
"customer_id": customer_id,
|
||||||
"fees_to_be": json.dumps(fees_to_be)
|
"fees_to_be": json.dumps(fees_to_be),
|
||||||
}
|
}
|
||||||
|
|
||||||
session_data = {
|
session_data = {
|
||||||
'customer': customer_id,
|
"customer": customer_id,
|
||||||
"payment_method_types": ["card","au_becs_debit"],
|
"payment_method_types": ["card", "au_becs_debit"],
|
||||||
'mode': 'subscription',
|
"mode": "subscription",
|
||||||
'line_items': line_items,
|
"line_items": line_items,
|
||||||
'success_url': f"{self.redirect_url}auth/waiting",
|
"success_url": f"{self.redirect_url}auth/waiting",
|
||||||
'cancel_url': f"{self.redirect_url}auth/waiting",
|
"cancel_url": f"{self.redirect_url}auth/waiting",
|
||||||
'metadata': metadata,
|
"metadata": metadata,
|
||||||
'subscription_data': {
|
"subscription_data": {"metadata": metadata},
|
||||||
'metadata': metadata
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
session = await stripe.checkout.Session.create_async(**session_data)
|
session = await stripe.checkout.Session.create_async(**session_data)
|
||||||
|
|
@ -261,18 +373,20 @@ class StripeServices:
|
||||||
payment_log = PaymentLogs(
|
payment_log = PaymentLogs(
|
||||||
customer_id=customer_id,
|
customer_id=customer_id,
|
||||||
account_id=account_id,
|
account_id=account_id,
|
||||||
amount=Decimal(str(fees_to_be["total"])), # Keep as Decimal for database storage
|
amount=Decimal(
|
||||||
|
str(fees_to_be["total"])
|
||||||
|
), # Keep as Decimal for database storage
|
||||||
clinic_id=clinic_id,
|
clinic_id=clinic_id,
|
||||||
unique_clinic_id=unique_clinic_id,
|
unique_clinic_id=unique_clinic_id,
|
||||||
payment_status="pending",
|
payment_status="pending",
|
||||||
metadata_logs=json.dumps(metadata)
|
metadata_logs=json.dumps(metadata),
|
||||||
)
|
)
|
||||||
|
|
||||||
new_payment_session = PaymentSessions(
|
new_payment_session = PaymentSessions(
|
||||||
session_id=session.id,
|
session_id=session.id,
|
||||||
customer_id=customer_id,
|
customer_id=customer_id,
|
||||||
clinic_id=clinic_id,
|
clinic_id=clinic_id,
|
||||||
status="pending"
|
status="pending",
|
||||||
)
|
)
|
||||||
|
|
||||||
self.db.add(payment_log)
|
self.db.add(payment_log)
|
||||||
|
|
@ -296,12 +410,16 @@ class StripeServices:
|
||||||
|
|
||||||
if event["type"] == "customer.subscription.deleted":
|
if event["type"] == "customer.subscription.deleted":
|
||||||
self.logger.info("customer subscription ended")
|
self.logger.info("customer subscription ended")
|
||||||
subscription_id = event["data"]["object"]["items"]["data"][0]["subscription"]
|
subscription_id = event["data"]["object"]["items"]["data"][0][
|
||||||
|
"subscription"
|
||||||
|
]
|
||||||
|
|
||||||
await self._subscription_expired(subscription_id)
|
await self._subscription_expired(subscription_id)
|
||||||
|
|
||||||
if event["type"] == "checkout.session.completed":
|
if event["type"] == "checkout.session.completed":
|
||||||
unique_clinic_id = event["data"]["object"]["metadata"]["unique_clinic_id"]
|
unique_clinic_id = event["data"]["object"]["metadata"][
|
||||||
|
"unique_clinic_id"
|
||||||
|
]
|
||||||
clinic_id = event["data"]["object"]["metadata"]["clinic_id"]
|
clinic_id = event["data"]["object"]["metadata"]["clinic_id"]
|
||||||
customer_id = event["data"]["object"]["metadata"]["customer_id"]
|
customer_id = event["data"]["object"]["metadata"]["customer_id"]
|
||||||
account_id = event["data"]["object"]["metadata"]["account_id"]
|
account_id = event["data"]["object"]["metadata"]["account_id"]
|
||||||
|
|
@ -310,15 +428,24 @@ class StripeServices:
|
||||||
session_id = event["data"]["object"]["id"]
|
session_id = event["data"]["object"]["id"]
|
||||||
subscription_id = event["data"]["object"]["subscription"]
|
subscription_id = event["data"]["object"]["subscription"]
|
||||||
|
|
||||||
await self._update_payment_log(unique_clinic_id, clinic_id, customer_id, account_id, total, metadata)
|
await self._update_payment_log(
|
||||||
|
unique_clinic_id,
|
||||||
|
clinic_id,
|
||||||
|
customer_id,
|
||||||
|
account_id,
|
||||||
|
total,
|
||||||
|
metadata,
|
||||||
|
)
|
||||||
|
|
||||||
await self._create_subscription_entry({
|
await self._create_subscription_entry(
|
||||||
"clinic_id": clinic_id,
|
{
|
||||||
"customer_id": customer_id,
|
"clinic_id": clinic_id,
|
||||||
"account_id": account_id,
|
"customer_id": customer_id,
|
||||||
"session_id": session_id,
|
"account_id": account_id,
|
||||||
"subscription_id": subscription_id,
|
"session_id": session_id,
|
||||||
})
|
"subscription_id": subscription_id,
|
||||||
|
}
|
||||||
|
)
|
||||||
# TODO: handle subscription period end
|
# TODO: handle subscription period end
|
||||||
|
|
||||||
return "OK"
|
return "OK"
|
||||||
|
|
@ -329,9 +456,19 @@ class StripeServices:
|
||||||
finally:
|
finally:
|
||||||
self.db.close()
|
self.db.close()
|
||||||
|
|
||||||
async def _update_payment_log(self, unique_clinic_id:str, clinic_id:int, customer_id:str, account_id:str, total:float, metadata:any):
|
async def _update_payment_log(
|
||||||
|
self,
|
||||||
|
unique_clinic_id: str,
|
||||||
|
clinic_id: int,
|
||||||
|
customer_id: str,
|
||||||
|
account_id: str,
|
||||||
|
total: float,
|
||||||
|
metadata: any,
|
||||||
|
):
|
||||||
try:
|
try:
|
||||||
self.db.query(PaymentSessions).filter(PaymentSessions.clinic_id == clinic_id).delete()
|
self.db.query(PaymentSessions).filter(
|
||||||
|
PaymentSessions.clinic_id == clinic_id
|
||||||
|
).delete()
|
||||||
|
|
||||||
payment_log = PaymentLogs(
|
payment_log = PaymentLogs(
|
||||||
customer_id=customer_id,
|
customer_id=customer_id,
|
||||||
|
|
@ -340,12 +477,12 @@ class StripeServices:
|
||||||
clinic_id=clinic_id,
|
clinic_id=clinic_id,
|
||||||
unique_clinic_id=unique_clinic_id,
|
unique_clinic_id=unique_clinic_id,
|
||||||
payment_status="paid",
|
payment_status="paid",
|
||||||
metadata_logs=json.dumps(metadata.to_dict())
|
metadata_logs=json.dumps(metadata.to_dict()),
|
||||||
)
|
)
|
||||||
self.db.add(payment_log)
|
self.db.add(payment_log)
|
||||||
|
|
||||||
clinic = self.db.query(Clinics).filter(Clinics.id == clinic_id).first()
|
clinic = self.db.query(Clinics).filter(Clinics.id == clinic_id).first()
|
||||||
|
|
||||||
if clinic:
|
if clinic:
|
||||||
clinic.status = ClinicStatus.UNDER_REVIEW
|
clinic.status = ClinicStatus.UNDER_REVIEW
|
||||||
self.db.add(clinic)
|
self.db.add(clinic)
|
||||||
|
|
@ -356,12 +493,12 @@ class StripeServices:
|
||||||
self.db.commit()
|
self.db.commit()
|
||||||
self.db.close()
|
self.db.close()
|
||||||
|
|
||||||
async def _create_subscription_entry(self,data:dict):
|
async def _create_subscription_entry(self, data: dict):
|
||||||
try:
|
try:
|
||||||
|
|
||||||
subscription = stripe.Subscription.retrieve(data["subscription_id"])
|
subscription = stripe.Subscription.retrieve(data["subscription_id"])
|
||||||
|
|
||||||
metadata_dict = json.loads(subscription.metadata)
|
metadata_dict = subscription.metadata
|
||||||
fees_to_be = json.loads(metadata_dict["fees_to_be"])
|
fees_to_be = json.loads(metadata_dict["fees_to_be"])
|
||||||
|
|
||||||
new_subscription = Subscriptions(
|
new_subscription = Subscriptions(
|
||||||
|
|
@ -374,9 +511,13 @@ class StripeServices:
|
||||||
per_call_charge=fees_to_be["per_call_charges"],
|
per_call_charge=fees_to_be["per_call_charges"],
|
||||||
subscription_id=data["subscription_id"],
|
subscription_id=data["subscription_id"],
|
||||||
status=subscription.status,
|
status=subscription.status,
|
||||||
current_period_start=subscription["items"]["data"][0]["current_period_start"],
|
current_period_start=subscription["items"]["data"][0][
|
||||||
current_period_end=subscription["items"]["data"][0]["current_period_end"],
|
"current_period_start"
|
||||||
metadata_logs=json.dumps(subscription.metadata)
|
],
|
||||||
|
current_period_end=subscription["items"]["data"][0][
|
||||||
|
"current_period_end"
|
||||||
|
],
|
||||||
|
metadata_logs=json.dumps(subscription.metadata),
|
||||||
)
|
)
|
||||||
self.db.add(new_subscription)
|
self.db.add(new_subscription)
|
||||||
|
|
||||||
|
|
@ -384,7 +525,7 @@ class StripeServices:
|
||||||
session_id=data["session_id"],
|
session_id=data["session_id"],
|
||||||
customer_id=data["customer_id"],
|
customer_id=data["customer_id"],
|
||||||
clinic_id=data["clinic_id"],
|
clinic_id=data["clinic_id"],
|
||||||
status="paid"
|
status="paid",
|
||||||
)
|
)
|
||||||
self.db.add(payment_session)
|
self.db.add(payment_session)
|
||||||
return
|
return
|
||||||
|
|
@ -393,26 +534,30 @@ class StripeServices:
|
||||||
finally:
|
finally:
|
||||||
self.db.commit()
|
self.db.commit()
|
||||||
self.db.close()
|
self.db.close()
|
||||||
|
|
||||||
async def _subscription_expired(self,subscription_id):
|
async def _subscription_expired(self, subscription_id):
|
||||||
try:
|
try:
|
||||||
subscription = stripe.Subscription.retrieve(subscription_id)
|
subscription = stripe.Subscription.retrieve(subscription_id)
|
||||||
|
|
||||||
db_subscription = self.db.query(Subscriptions).filter(Subscriptions.subscription_id == subscription_id).first()
|
db_subscription = (
|
||||||
|
self.db.query(Subscriptions)
|
||||||
|
.filter(Subscriptions.subscription_id == subscription_id)
|
||||||
|
.first()
|
||||||
|
)
|
||||||
|
|
||||||
if not db_subscription:
|
if not db_subscription:
|
||||||
self.logger.error("Subscription not found!")
|
self.logger.error("Subscription not found!")
|
||||||
raise Exception("Subscription not found!")
|
raise Exception("Subscription not found!")
|
||||||
|
|
||||||
db_subscription.status = subscription.status
|
db_subscription.status = subscription.status
|
||||||
self.db.add(db_subscription)
|
self.db.add(db_subscription)
|
||||||
|
|
||||||
# TODO: update clinic status
|
# TODO: update clinic status
|
||||||
# TODO: send email to user
|
# TODO: send email to user
|
||||||
|
|
||||||
return
|
return
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.logger.error(f"Error ending subscription: {e}")
|
self.logger.error(f"Error ending subscription: {e}")
|
||||||
finally:
|
finally:
|
||||||
self.db.commit()
|
self.db.commit()
|
||||||
self.db.close()
|
self.db.close()
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import asyncio
|
import asyncio
|
||||||
from loguru import logger
|
from loguru import logger
|
||||||
|
from sqlalchemy import or_
|
||||||
from sqlalchemy.orm import Session
|
from sqlalchemy.orm import Session
|
||||||
|
|
||||||
from database import get_db
|
from database import get_db
|
||||||
|
|
@ -62,23 +63,6 @@ class UserServices:
|
||||||
self.db.add(new_user)
|
self.db.add(new_user)
|
||||||
self.db.flush() # Flush to get the user ID without committing
|
self.db.flush() # Flush to get the user ID without committing
|
||||||
|
|
||||||
stripe_customer, stripe_account = await asyncio.gather(
|
|
||||||
self.stripe_service.create_customer(
|
|
||||||
new_user.id, user.email, user.username
|
|
||||||
),
|
|
||||||
self.stripe_service.create_account(
|
|
||||||
new_user.id, user.email, user.username, user.mobile
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
# Create stripe user
|
|
||||||
stripe_user = StripeUsers(
|
|
||||||
user_id=new_user.id,
|
|
||||||
customer_id=stripe_customer.id,
|
|
||||||
account_id=stripe_account.id,
|
|
||||||
)
|
|
||||||
self.db.add(stripe_user)
|
|
||||||
|
|
||||||
# Get clinic data
|
# Get clinic data
|
||||||
clinic = user_data.clinic
|
clinic = user_data.clinic
|
||||||
|
|
||||||
|
|
@ -90,18 +74,35 @@ class UserServices:
|
||||||
if char.isalnum() or char == "-" or char == "_"
|
if char.isalnum() or char == "-" or char == "_"
|
||||||
)
|
)
|
||||||
existing_clinic = (
|
existing_clinic = (
|
||||||
self.db.query(Clinics).filter(Clinics.domain == domain).first()
|
self.db.query(Clinics).filter(
|
||||||
|
or_(Clinics.domain == domain,
|
||||||
|
Clinics.email == clinic.email,
|
||||||
|
Clinics.phone == clinic.phone,
|
||||||
|
Clinics.emergency_phone == clinic.emergency_phone,
|
||||||
|
Clinics.abn_number == clinic.abn_number,
|
||||||
|
)
|
||||||
|
).first()
|
||||||
)
|
)
|
||||||
|
|
||||||
if existing_clinic:
|
if existing_clinic:
|
||||||
# This will trigger rollback in the exception handler
|
# This will trigger rollback in the exception handler
|
||||||
raise ValidationException("Clinic with same domain already exists")
|
if existing_clinic.domain == domain:
|
||||||
|
raise ValidationException("Clinic with same name already exists")
|
||||||
|
if existing_clinic.email == clinic.email:
|
||||||
|
raise ValidationException("Clinic with same email already exists")
|
||||||
|
if existing_clinic.phone == clinic.phone:
|
||||||
|
raise ValidationException("Clinic with same phone already exists")
|
||||||
|
if existing_clinic.emergency_phone == clinic.emergency_phone:
|
||||||
|
raise ValidationException("Clinic with same emergency phone already exists")
|
||||||
|
if existing_clinic.abn_number == clinic.abn_number:
|
||||||
|
raise ValidationException("Clinic with same ABN already exists")
|
||||||
|
|
||||||
# Create clinic instance
|
# Create clinic instance
|
||||||
new_clinic = Clinics(
|
new_clinic = Clinics(
|
||||||
name=clinic.name,
|
name=clinic.name,
|
||||||
address=clinic.address,
|
address=clinic.address,
|
||||||
phone=clinic.phone,
|
phone=clinic.phone,
|
||||||
|
emergency_phone=clinic.emergency_phone,
|
||||||
email=clinic.email,
|
email=clinic.email,
|
||||||
integration=clinic.integration,
|
integration=clinic.integration,
|
||||||
pms_id=clinic.pms_id,
|
pms_id=clinic.pms_id,
|
||||||
|
|
@ -151,6 +152,24 @@ class UserServices:
|
||||||
clinic.email
|
clinic.email
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
stripe_customer, stripe_account = await asyncio.gather(
|
||||||
|
self.stripe_service.create_customer(
|
||||||
|
new_user.id, user.email, user.username
|
||||||
|
),
|
||||||
|
self.stripe_service.create_account(
|
||||||
|
new_user.id, user.email, user.username, user.mobile
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
# Create stripe user
|
||||||
|
stripe_user = StripeUsers(
|
||||||
|
user_id=new_user.id,
|
||||||
|
customer_id=stripe_customer.id,
|
||||||
|
account_id=stripe_account.id,
|
||||||
|
)
|
||||||
|
self.db.add(stripe_user)
|
||||||
|
|
||||||
signup_pricing = await self.dashboard_service.get_signup_pricing_master()
|
signup_pricing = await self.dashboard_service.get_signup_pricing_master()
|
||||||
|
|
||||||
fees_to_be = {
|
fees_to_be = {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue