|
|
|
|
|
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 |
|
|
|
|
|
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) |
|
|
|
|
|
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") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self.user |
|
await self.user.create_subscription(self.plan) |
|
self.status = "subscription-created" |
|
await self.save() |
|
|
|
await self.user.send_payment_success_message( |
|
amount=self.amount, plan_name=self.plan.name |
|
) |
|
else: |
|
self.status = "insufficient-funds" |
|
await self.save() |
|
|
|
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") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
user = await self.user |
|
|
|
self.user |
|
await self.user.create_subscription(self.plan) |
|
self.status = "subscription-created" |
|
await self.save() |
|
|
|
await self.user.send_payment_success_message( |
|
amount=self.amount, plan_name=self.plan.name |
|
) |
|
|
|
else: |
|
self.status = "insufficient-funds" |
|
await self.save() |
|
|
|
await user.send_insufficient_funds_message( |
|
required_amount=self.plan.amount, attempted_amount=self.amount |
|
) |
|
elif not self.plan and self.user: |
|
|
|
user = await self.user |
|
user.balance += self.amount |
|
await user.save() |
|
self.status = "balance-assigned" |
|
await self.save() |
|
|
|
await user.send_payment_success_message(amount=self.amount) |
|
|