Creditsupdates in fotoer wdigets adn hoemapge and singe site settigns page #Run MIgration 0033 #MAJOR

This commit is contained in:
IGNY8 VPS (Salman)
2026-01-12 07:22:08 +00:00
parent 368601f68c
commit b390e02aa5
17 changed files with 251 additions and 45 deletions

View File

@@ -336,10 +336,10 @@ class CreditService:
@staticmethod
@transaction.atomic
def deduct_credits(account, amount, operation_type, description, metadata=None, cost_usd=None, model_used=None, tokens_input=None, tokens_output=None, related_object_type=None, related_object_id=None):
def deduct_credits(account, amount, operation_type, description, metadata=None, cost_usd=None, model_used=None, tokens_input=None, tokens_output=None, related_object_type=None, related_object_id=None, site=None):
"""
Deduct credits and log transaction.
Args:
account: Account instance
amount: Number of credits to deduct
@@ -352,20 +352,21 @@ class CreditService:
tokens_output: Optional output tokens
related_object_type: Optional related object type
related_object_id: Optional related object ID
site: Optional Site instance or site_id
Returns:
int: New credit balance
"""
# Check sufficient credits (legacy: amount is already calculated)
CreditService.check_credits_legacy(account, amount)
# Store previous balance for low credits check
previous_balance = account.credits
# Deduct from account.credits
account.credits -= amount
account.save(update_fields=['credits'])
# Create CreditTransaction
CreditTransaction.objects.create(
account=account,
@@ -375,10 +376,11 @@ class CreditService:
description=description,
metadata=metadata or {}
)
# Create CreditUsageLog
CreditUsageLog.objects.create(
account=account,
site=site,
operation_type=operation_type,
credits_used=amount,
cost_usd=cost_usd,
@@ -389,30 +391,31 @@ class CreditService:
related_object_id=related_object_id,
metadata=metadata or {}
)
# Check and send low credits warning if applicable
_check_low_credits_warning(account, previous_balance)
return account.credits
@staticmethod
@transaction.atomic
def deduct_credits_for_operation(
account,
operation_type,
tokens_input,
account,
operation_type,
tokens_input,
tokens_output,
description=None,
metadata=None,
cost_usd=None,
model_used=None,
related_object_type=None,
related_object_id=None
description=None,
metadata=None,
cost_usd=None,
model_used=None,
related_object_type=None,
related_object_id=None,
site=None
):
"""
Deduct credits for an operation based on actual token usage.
This is the ONLY way to deduct credits in the token-based system.
Args:
account: Account instance
operation_type: Type of operation
@@ -424,10 +427,11 @@ class CreditService:
model_used: Optional AI model used
related_object_type: Optional related object type
related_object_id: Optional related object ID
site: Optional Site instance or site_id
Returns:
int: New credit balance
Raises:
ValueError: If tokens_input or tokens_output not provided
"""
@@ -437,18 +441,18 @@ class CreditService:
f"tokens_input and tokens_output are REQUIRED for credit deduction. "
f"Got: tokens_input={tokens_input}, tokens_output={tokens_output}"
)
# Calculate credits from actual token usage
credits_required = CreditService.calculate_credits_from_tokens(
operation_type, tokens_input, tokens_output
)
# Check sufficient credits
if account.credits < credits_required:
raise InsufficientCreditsError(
f"Insufficient credits. Required: {credits_required}, Available: {account.credits}"
)
# Auto-generate description if not provided
if not description:
total_tokens = tokens_input + tokens_output
@@ -456,7 +460,7 @@ class CreditService:
f"{operation_type}: {total_tokens} tokens "
f"({tokens_input} in, {tokens_output} out) = {credits_required} credits"
)
return CreditService.deduct_credits(
account=account,
amount=credits_required,
@@ -468,7 +472,8 @@ class CreditService:
tokens_input=tokens_input,
tokens_output=tokens_output,
related_object_type=related_object_type,
related_object_id=related_object_id
related_object_id=related_object_id,
site=site
)
@staticmethod
@@ -513,11 +518,12 @@ class CreditService:
metadata: dict = None,
cost_usd: float = None,
related_object_type: str = None,
related_object_id: int = None
related_object_id: int = None,
site = None
):
"""
Deduct credits for image generation based on model's credits_per_image.
Args:
account: Account instance
model_name: AI model used (e.g., 'dall-e-3', 'flux-1-1-pro')
@@ -527,20 +533,21 @@ class CreditService:
cost_usd: Optional cost in USD
related_object_type: Optional related object type
related_object_id: Optional related object ID
site: Optional Site instance or site_id
Returns:
int: New credit balance
"""
credits_required = CreditService.calculate_credits_for_image(model_name, num_images)
if account.credits < credits_required:
raise InsufficientCreditsError(
f"Insufficient credits. Required: {credits_required}, Available: {account.credits}"
)
if not description:
description = f"Image generation: {num_images} images with {model_name} = {credits_required} credits"
return CreditService.deduct_credits(
account=account,
amount=credits_required,
@@ -552,6 +559,7 @@ class CreditService:
tokens_input=None,
tokens_output=None,
related_object_type=related_object_type,
related_object_id=related_object_id
related_object_id=related_object_id,
site=site
)