# App/Payments/Model.py from tortoise import fields from tortoise.models import Model import datetime from decimal import Decimal from App.Plans.Model import Plan from App.Subscriptions.Model import Subscription from .Schema import PaymentMethod from App.Android.Android import AndroidClient from App.Templates.Templates import MessageTemplate import logging # Configure logging logger = logging.getLogger(__name__) logger.setLevel(logging.INFO) handler = logging.StreamHandler() formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s") handler.setFormatter(formatter) logger.addHandler(handler) class Payment(Model): id = fields.UUIDField(pk=True) user = fields.ForeignKeyField("models.User", related_name="payments", null=True) plan = fields.ForeignKeyField( "models.Plan", related_name="payments", null=True, description="Plan associated with the payment", ) amount = fields.DecimalField( max_digits=10, decimal_places=2, description="Payment amount" ) status = fields.CharField( max_length=50, default="pending", description="Payment status (e.g., pending, completed, failed, balance-assigned)", ) payment_method = fields.CharField( max_length=50, choices=PaymentMethod.CHOICES, description="Payment method" ) transaction_id = fields.CharField( max_length=100, unique=True, null=True, description="Unique transaction ID for payment (for methods like Lipa Number)", ) created_time = fields.DatetimeField(auto_now_add=True) updated_time = fields.DatetimeField(auto_now=True) # Initialize AndroidClient and MessageTemplate as class variables android_client = AndroidClient() message_templates = MessageTemplate() class Meta: table = "payments" async def create_subscription_if_cash(self): if self.payment_method == PaymentMethod.CASH and self.user and self.plan: if self.amount >= self.plan.amount: await self.fetch_related("user", "plan") # expiration_time = datetime.datetime.now() + datetime.timedelta( # hours=self.plan.duration # ) # # Create the subscription # await Subscription.create( # user=self.user, # duration=self.plan.duration, # download_mb=self.plan.download_speed * 1024, # upload_mb=self.plan.upload_speed * 1024, # created_time=datetime.datetime.now(), # expiration_time=expiration_time, # active=True, # ) self.user await self.user.create_subscription(self.plan) self.status = "subscription-created" await self.save() # Send payment success message with subscription details await self.user.send_payment_success_message( amount=self.amount, plan_name=self.plan.name ) else: self.status = "insufficient-funds" await self.save() # Send insufficient funds message await self.user.send_insufficient_funds_message( required_amount=self.plan.amount, attempted_amount=self.amount ) async def create_subscription_or_balance(self): if self.user and self.plan: if self.amount >= self.plan.amount: await self.fetch_related("user", "plan") # expiration_time = datetime.datetime.now() + datetime.timedelta( # hours=self.plan.duration # ) # # Create the subscription # await Subscription.create( # user=self.user, # duration=self.plan.duration, # download_mb=self.plan.download_speed * 1024, # upload_mb=self.plan.upload_speed * 1024, # created_time=datetime.datetime.now(), # expiration_time=expiration_time, # active=True, # ) user = await self.user self.user await self.user.create_subscription(self.plan) self.status = "subscription-created" await self.save() # Send payment success message with subscription details await self.user.send_payment_success_message( amount=self.amount, plan_name=self.plan.name ) else: self.status = "insufficient-funds" await self.save() # Send insufficient funds message await user.send_insufficient_funds_message( required_amount=self.plan.amount, attempted_amount=self.amount ) elif not self.plan and self.user: # Await the related user object user = await self.user user.balance += self.amount await user.save() self.status = "balance-assigned" await self.save() # Send payment success message with balance assignment await user.send_payment_success_message(amount=self.amount)