Open igorsimb opened 3 weeks ago
Step-by-Step Implementation: Define Quota Settings Based on Status:
First, define the quota settings for each status. This can be done in your settings or as a dictionary within your task file.
# myapp/constants.py
QUOTA_SETTINGS = {
'TRIALING': {
'user_lifetime_hours': 10,
'max_allowed_skus': 50,
'manual_updates': 5,
'scheduled_updates': 5,
},
'ACTIVE': {
'user_lifetime_hours': 100,
'max_allowed_skus': 500,
'manual_updates': 50,
'scheduled_updates': 50,
},
'EXEMPT': {
'user_lifetime_hours': 0, # Or some default value
'max_allowed_skus': 0,
'manual_updates': 0,
'scheduled_updates': 0,
},
'CANCELED': {
'user_lifetime_hours': 0,
'max_allowed_skus': 0,
'manual_updates': 0,
'scheduled_updates': 0,
},
'TRIAL_EXPIRED': {
'user_lifetime_hours': 0,
'max_allowed_skus': 0,
'manual_updates': 0,
'scheduled_updates': 0,
}
}
create_user_quota
It should create quota depending on the chosen plan or Status.
Modify the Celery task to reset quotas based on the user's current status.
# myapp/tasks.py
from celery import shared_task
from django.db import transaction
from myapp.models import UserQuota, Tenant
from myapp.constants import QUOTA_SETTINGS
@shared_task
def reset_quotas():
with transaction.atomic():
tenants = Tenant.objects.all()
for tenant in tenants:
status_name = Tenant.Status(tenant.status).name
quotas = QUOTA_SETTINGS.get(status_name, {
'user_lifetime_hours': 0,
'max_allowed_skus': 0,
'manual_updates': 0,
'scheduled_updates': 0
})
UserQuota.objects.filter(user__tenant=tenant).update(
user_lifetime_hours=quotas['user_lifetime_hours'],
max_allowed_skus=quotas['max_allowed_skus'],
manual_updates=quotas['manual_updates'],
scheduled_updates=quotas['scheduled_updates']
)
get()
: A method of dictionaries in Python that retrieves the value for a given key. If the key is not found, it returns a default value instead of raising an error.
The default value is a dictionary where all quota values are set to 0. This ensures that even if a tenant has an unknown or unexpected status, their quotas will be reset to zero instead of causing an error.
Ensure the task is scheduled to run at 12 AM on the 1st of every month.
# myapp/celery.py
from celery import Celery
from celery.schedules import crontab
app = Celery('myapp')
app.conf.beat_schedule = {
'reset-quotas-every-month': {
'task': 'myapp.tasks.reset_quotas',
'schedule': crontab(minute=0, hour=0, day_of_month=1),
},
}
Explanation: Quota Settings: The QUOTA_SETTINGS dictionary defines the default quotas for each status. Adjust these values according to your requirements.
Celery Task:
The reset_quotas task iterates over all tenants. For each tenant, it determines their status and fetches the corresponding quota settings. The quotas are then reset using the update method of the UserQuota model, ensuring all related quotas are updated in a single query. Transactional Integrity: The task is wrapped in a transaction to ensure atomicity, meaning all updates will be rolled back if any part of the task fails.
class UserQuota(models.Model):
user = models.ForeignKey(CustomUser, on_delete=models.CASCADE, related_name="user_quotas")
user_lifetime_hours = models.PositiveIntegerField(default=0, blank=True, null=True)
max_allowed_skus = models.PositiveIntegerField(default=0, blank=True, null=True)
manual_updates = models.PositiveIntegerField(default=0, blank=True, null=True)
scheduled_updates = models.PositiveIntegerField(default=0, blank=True, null=True)
allowed_parse_units = models.PositiveIntegerField(default=0, blank=True, null=True) # New field for checks Единица проверки
update_user_quota_for_parse_units
that updates the checks (see update_user_quota_for_max_allowed_sku
for a similar function)QuotaExceededException
messagesif user.is_demo_user
condition to "if user has any quotas"
Currently the quotas are only applicable to Demo users. We need to expand the quotas feature to apply to every user. For that:
UserQuota
model should take into consideration the number of "checks" per user on a plan (check = items * number of parsings). E.g. A plan allows for 30 items and 30000 checks (i.e. 1000 checks per item per month, i.e. 33 checks per item per day). E.g. see how priceva sees the "checks": https://priceva.ru/knowledge/chto-takoe-proverka-2/Resetting Quotas. Quotas should be reset at the start of every monthChange Tenant'sStatus
class to have "FREE" together with "TRIALING"UserQuota
's fields can benull
andblank
for users with EXEMPT status (i.e. no restrictions).