multi sector clustering erroro rasing, adn tasks page word coutn monthly limits removal
This commit is contained in:
@@ -1032,7 +1032,7 @@ from rest_framework.decorators import api_view, permission_classes
|
||||
def get_usage_summary(request):
|
||||
"""
|
||||
Get comprehensive usage summary for current account.
|
||||
Includes hard limits (sites, users, keywords, clusters) and monthly limits (ideas, words, images).
|
||||
Includes hard limits (sites, users, keywords) and monthly limits (ahrefs queries only).
|
||||
|
||||
GET /api/v1/billing/usage-summary/
|
||||
"""
|
||||
|
||||
@@ -257,12 +257,11 @@ class BillingConfiguration(models.Model):
|
||||
|
||||
class PlanLimitUsage(AccountBaseModel):
|
||||
"""
|
||||
Track monthly usage of plan limits (ideas, words, images, prompts)
|
||||
Track monthly usage of plan limits (ideas, images, prompts)
|
||||
Resets at start of each billing period
|
||||
"""
|
||||
LIMIT_TYPE_CHOICES = [
|
||||
('content_ideas', 'Content Ideas'),
|
||||
('content_words', 'Content Words'),
|
||||
('images_basic', 'Basic Images'),
|
||||
('images_premium', 'Premium Images'),
|
||||
('image_prompts', 'Image Prompts'),
|
||||
|
||||
@@ -358,31 +358,8 @@ class Content(SoftDeletableModel, SiteSectorBaseModel):
|
||||
|
||||
super().save(*args, **kwargs)
|
||||
|
||||
# Increment usage for new content or if word count increased
|
||||
if self.content_html and self.word_count:
|
||||
# Only count newly generated words
|
||||
new_words = self.word_count - old_word_count if not is_new else self.word_count
|
||||
|
||||
if new_words > 0:
|
||||
from igny8_core.business.billing.services.limit_service import LimitService
|
||||
try:
|
||||
# Get account from site
|
||||
account = self.site.account if self.site else None
|
||||
if account:
|
||||
LimitService.increment_usage(
|
||||
account=account,
|
||||
limit_type='content_words',
|
||||
amount=new_words,
|
||||
metadata={
|
||||
'content_id': self.id,
|
||||
'content_title': self.title,
|
||||
'site_id': self.site.id if self.site else None,
|
||||
}
|
||||
)
|
||||
except Exception as e:
|
||||
import logging
|
||||
logger = logging.getLogger(__name__)
|
||||
logger.error(f"Error incrementing word usage for content {self.id}: {str(e)}")
|
||||
# NOTE: Content words no longer tracked as a monthly plan limit.
|
||||
# Credits are the only enforcement for content generation.
|
||||
|
||||
def soft_delete(self, user=None, reason=None, retention_days=None):
|
||||
"""
|
||||
|
||||
@@ -30,20 +30,12 @@ class ContentGenerationService:
|
||||
Raises:
|
||||
InsufficientCreditsError: If account doesn't have enough credits
|
||||
"""
|
||||
from igny8_core.business.billing.services.limit_service import LimitService, MonthlyLimitExceededError
|
||||
|
||||
# Get tasks
|
||||
tasks = Tasks.objects.filter(id__in=task_ids, account=account)
|
||||
|
||||
# Calculate estimated credits needed based on word count
|
||||
total_word_count = sum(task.word_count or 1000 for task in tasks)
|
||||
|
||||
# Check monthly word count limit
|
||||
try:
|
||||
LimitService.check_monthly_limit(account, 'content_words', amount=total_word_count)
|
||||
except MonthlyLimitExceededError as e:
|
||||
raise InsufficientCreditsError(str(e))
|
||||
|
||||
# Check credits
|
||||
try:
|
||||
self.credit_service.check_credits(account, 'content_generation', total_word_count)
|
||||
|
||||
@@ -292,7 +292,6 @@ class TasksViewSet(SiteSectorModelViewSet):
|
||||
content_type_filter = request.query_params.get('content_type', '')
|
||||
content_structure_filter = request.query_params.get('content_structure', '')
|
||||
cluster_filter = request.query_params.get('cluster', '')
|
||||
source_filter = request.query_params.get('source', '')
|
||||
search = request.query_params.get('search', '')
|
||||
|
||||
# Apply search to base queryset
|
||||
@@ -310,8 +309,6 @@ class TasksViewSet(SiteSectorModelViewSet):
|
||||
status_qs = status_qs.filter(content_structure=content_structure_filter)
|
||||
if cluster_filter:
|
||||
status_qs = status_qs.filter(cluster_id=cluster_filter)
|
||||
if source_filter:
|
||||
status_qs = status_qs.filter(source=source_filter)
|
||||
statuses = list(set(status_qs.values_list('status', flat=True)))
|
||||
statuses = sorted([s for s in statuses if s])
|
||||
status_labels = {
|
||||
@@ -333,8 +330,6 @@ class TasksViewSet(SiteSectorModelViewSet):
|
||||
type_qs = type_qs.filter(content_structure=content_structure_filter)
|
||||
if cluster_filter:
|
||||
type_qs = type_qs.filter(cluster_id=cluster_filter)
|
||||
if source_filter:
|
||||
type_qs = type_qs.filter(source=source_filter)
|
||||
content_types = list(set(type_qs.values_list('content_type', flat=True)))
|
||||
content_types = sorted([t for t in content_types if t])
|
||||
type_labels = {
|
||||
@@ -356,8 +351,6 @@ class TasksViewSet(SiteSectorModelViewSet):
|
||||
structure_qs = structure_qs.filter(content_type=content_type_filter)
|
||||
if cluster_filter:
|
||||
structure_qs = structure_qs.filter(cluster_id=cluster_filter)
|
||||
if source_filter:
|
||||
structure_qs = structure_qs.filter(source=source_filter)
|
||||
structures = list(set(structure_qs.values_list('content_structure', flat=True)))
|
||||
structures = sorted([s for s in structures if s])
|
||||
structure_labels = {
|
||||
@@ -381,8 +374,6 @@ class TasksViewSet(SiteSectorModelViewSet):
|
||||
cluster_qs = cluster_qs.filter(content_type=content_type_filter)
|
||||
if content_structure_filter:
|
||||
cluster_qs = cluster_qs.filter(content_structure=content_structure_filter)
|
||||
if source_filter:
|
||||
cluster_qs = cluster_qs.filter(source=source_filter)
|
||||
from igny8_core.modules.planner.models import Clusters
|
||||
cluster_ids = list(set(
|
||||
cluster_qs.exclude(cluster_id__isnull=True)
|
||||
@@ -394,35 +385,12 @@ class TasksViewSet(SiteSectorModelViewSet):
|
||||
for c in clusters
|
||||
]
|
||||
|
||||
# Get sources (filtered by other fields)
|
||||
source_qs = base_qs
|
||||
if status_filter:
|
||||
source_qs = source_qs.filter(status=status_filter)
|
||||
if content_type_filter:
|
||||
source_qs = source_qs.filter(content_type=content_type_filter)
|
||||
if content_structure_filter:
|
||||
source_qs = source_qs.filter(content_structure=content_structure_filter)
|
||||
if cluster_filter:
|
||||
source_qs = source_qs.filter(cluster_id=cluster_filter)
|
||||
sources = list(set(source_qs.values_list('source', flat=True)))
|
||||
sources = sorted([s for s in sources if s])
|
||||
source_labels = {
|
||||
'manual': 'Manual',
|
||||
'planner': 'Planner',
|
||||
'ai': 'AI',
|
||||
}
|
||||
source_options = [
|
||||
{'value': s, 'label': source_labels.get(s, s.title())}
|
||||
for s in sources
|
||||
]
|
||||
|
||||
return success_response(
|
||||
data={
|
||||
'statuses': status_options,
|
||||
'content_types': content_type_options,
|
||||
'content_structures': content_structure_options,
|
||||
'clusters': cluster_options,
|
||||
'sources': source_options,
|
||||
},
|
||||
request=request
|
||||
)
|
||||
@@ -970,16 +938,6 @@ class ContentViewSet(SiteSectorModelViewSet):
|
||||
word_count = calculate_word_count(html_content)
|
||||
serializer.validated_data['word_count'] = word_count
|
||||
|
||||
# Check monthly word count limit (enforces ALL entry points: manual, import, AI, automation)
|
||||
if account and word_count > 0:
|
||||
from igny8_core.business.billing.services.limit_service import LimitService, MonthlyLimitExceededError
|
||||
from rest_framework.exceptions import ValidationError
|
||||
|
||||
try:
|
||||
LimitService.check_monthly_limit(account, 'content_words', amount=word_count)
|
||||
except MonthlyLimitExceededError as e:
|
||||
raise ValidationError(str(e))
|
||||
|
||||
if account:
|
||||
serializer.save(account=account)
|
||||
else:
|
||||
|
||||
@@ -22,11 +22,7 @@ def reset_monthly_plan_limits():
|
||||
It finds all accounts where the billing period has ended and resets their monthly usage.
|
||||
|
||||
Monthly limits that get reset:
|
||||
- content_ideas
|
||||
- content_words
|
||||
- images_basic
|
||||
- images_premium
|
||||
- image_prompts
|
||||
- ahrefs_queries
|
||||
|
||||
Hard limits (sites, users, keywords, clusters) are NOT reset.
|
||||
"""
|
||||
|
||||
Reference in New Issue
Block a user