payemnt billing and credits refactoring
This commit is contained in:
@@ -0,0 +1,34 @@
|
||||
# Generated by Django 5.2.10 on 2026-01-20 06:11
|
||||
|
||||
import django.core.validators
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('igny8_core_auth', '0034_add_user_phone'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='account',
|
||||
name='bonus_credits',
|
||||
field=models.IntegerField(default=0, help_text='Purchased/bonus credits (never expire, never reset)', validators=[django.core.validators.MinValueValidator(0)]),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='historicalaccount',
|
||||
name='bonus_credits',
|
||||
field=models.IntegerField(default=0, help_text='Purchased/bonus credits (never expire, never reset)', validators=[django.core.validators.MinValueValidator(0)]),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='account',
|
||||
name='credits',
|
||||
field=models.IntegerField(default=0, help_text='Plan credits (reset on renewal)', validators=[django.core.validators.MinValueValidator(0)]),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='historicalaccount',
|
||||
name='credits',
|
||||
field=models.IntegerField(default=0, help_text='Plan credits (reset on renewal)', validators=[django.core.validators.MinValueValidator(0)]),
|
||||
),
|
||||
]
|
||||
@@ -83,7 +83,8 @@ class Account(SoftDeletableModel):
|
||||
)
|
||||
stripe_customer_id = models.CharField(max_length=255, blank=True, null=True)
|
||||
plan = models.ForeignKey('igny8_core_auth.Plan', on_delete=models.PROTECT, related_name='accounts')
|
||||
credits = models.IntegerField(default=0, validators=[MinValueValidator(0)])
|
||||
credits = models.IntegerField(default=0, validators=[MinValueValidator(0)], help_text="Plan credits (reset on renewal)")
|
||||
bonus_credits = models.IntegerField(default=0, validators=[MinValueValidator(0)], help_text="Purchased/bonus credits (never expire, never reset)")
|
||||
status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='trial')
|
||||
payment_method = models.CharField(
|
||||
max_length=30,
|
||||
@@ -143,6 +144,11 @@ class Account(SoftDeletableModel):
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
@property
|
||||
def total_credits(self):
|
||||
"""Total available credits (plan + bonus). Use this for balance checks."""
|
||||
return self.credits + self.bonus_credits
|
||||
|
||||
@property
|
||||
def default_payment_method(self):
|
||||
"""Get default payment method from AccountPaymentMethod table"""
|
||||
|
||||
@@ -41,6 +41,11 @@ class AccountSerializer(serializers.ModelSerializer):
|
||||
plan = PlanSerializer(read_only=True)
|
||||
plan_id = serializers.PrimaryKeyRelatedField(queryset=Plan.objects.filter(is_active=True), write_only=True, source='plan', required=False)
|
||||
subscription = SubscriptionSerializer(read_only=True, allow_null=True)
|
||||
total_credits = serializers.SerializerMethodField()
|
||||
|
||||
def get_total_credits(self, obj):
|
||||
"""Return total available credits (plan + bonus)."""
|
||||
return obj.credits + obj.bonus_credits
|
||||
|
||||
def validate_plan_id(self, value):
|
||||
"""Validate plan_id is provided during creation."""
|
||||
@@ -52,7 +57,7 @@ class AccountSerializer(serializers.ModelSerializer):
|
||||
model = Account
|
||||
fields = [
|
||||
'id', 'name', 'slug', 'owner', 'plan', 'plan_id',
|
||||
'credits', 'status', 'payment_method',
|
||||
'credits', 'bonus_credits', 'total_credits', 'status', 'payment_method',
|
||||
'subscription', 'billing_country',
|
||||
'account_timezone', 'timezone_mode', 'timezone_offset',
|
||||
'created_at'
|
||||
|
||||
Reference in New Issue
Block a user