from tortoise import fields from tortoise.models import Model import datetime from App.Plans.Model import Plan class Subscription(Model): id = fields.UUIDField(pk=True) user = fields.ForeignKeyField("models.User", related_name="subscriptions") plan = fields.ForeignKeyField( "models.Plan", related_name="subscriptions", null=True, description="Plan associated with the subscription", ) active = fields.BooleanField(default=True) duration = fields.IntField(description="Duration in hours") download_mb = fields.FloatField( default=0.0, description="Download usage in megabytes" ) upload_mb = fields.FloatField(default=0.0, description="Upload usage in megabytes") created_time = fields.DatetimeField(auto_now_add=True) expiration_time = fields.DatetimeField(null=True) class Meta: table = "subscriptions" async def save(self, *args, **kwargs): # Calculate expiration_time if it's not set and we have created_time and duration if not self.expiration_time and self.created_time and self.duration: self.expiration_time = self.created_time + datetime.timedelta( hours=self.duration ) await super().save(*args, **kwargs) async def time_remaining(self) -> float: """ Calculate the remaining time for the subscription in hours. Returns: float: Number of hours remaining. Returns 0 if subscription has expired. """ if not self.active: return 0.0 current_time = datetime.datetime.now(self.created_time.tzinfo) # If subscription has expired, deactivate it if current_time >= self.expiration_time: self.active = False await self.save() return 0.0 # Calculate remaining time in hours time_diff = self.expiration_time - current_time remaining_hours = time_diff.total_seconds() / 3600 return round(remaining_hours, 2) async def is_valid(self) -> bool: """ Check if the subscription is still valid (active and not expired). Returns: bool: True if subscription is valid, False otherwise. """ remaining_time = await self.time_remaining() return self.active and remaining_time > 0