Реализация логики на основе повторяющейся подписки в Django
У меня есть две модели. Модель плана, состоящая из трех планов, и модель подписки. Пользователю разрешено иметь только один активный план в одно время. Логика заключается в том, что когда пользователь впервые подписывается на план, по умолчанию status
будет pending
. После того, как администратор сайта подтвердит подписку (депозит), он переключит булево поле active
, и автоматически статус изменится на Confirmed
.
Теперь, где у меня возникают проблемы, так это с реализацией того, что происходит после подтверждения подписки. Я постараюсь объяснить логику как можно подробнее. Предполагается, что пользователь будет получать ежедневную прибыль до истечения срока действия плана. Позвольте мне привести пример: Предположим, пользователь А подписался на basic plan
. Подписка basic plan
имеет ежедневный процентный бонус 10% и длится 7 дней (duration
). Теперь после того, как администратор активирует подписку, пользователь должен получать ежедневную прибыль в размере 10% от его инвестиций в течение 7 дней. Если предположить, что он подписывается на $100.00, то к концу первого дня его баланс должен составлять $110.00, и так далее. Затем, после истечения срока действия плана, статус должен автоматически измениться на Expired
, поле active
изменится на False, а процент перестанет прибавляться.
Вот мой вопрос, как реализовать эту логику ежедневного автоматического увеличения баланса пользователя до истечения срока действия его текущего плана, и как автоматически деактивировать подписку после истечения срока действия. Я пытался использовать циклы, но это была ужасная идея. Я видел несколько статей о Celery, RQ, threading, Cron и так далее. Но я не знаю, как поступить ни с одной из них. Может ли кто-нибудь, пожалуйста, помочь мне с решением проблемы. Я был бы признателен, если бы человек реализовал логику, используя любой инструмент по своему выбору, и объяснил мне идею, лежащую в ее основе. Вместо того чтобы направлять меня от одной статьи к другой. Спасибо. Если вам нужны дополнительные разъяснения, пожалуйста, дайте мне знать. Я использую PostgreSQL.
Вот моя модель плана
class Plan(models.Model):
SUB_PLAN = (
('Basic', 'Basic Plan'),
('Gold', 'Gold Plan'),
('Platinum', 'Platinum Plan')
)
plan_name = models.CharField(max_length=8, choices=SUB_PLAN)
percent = models.PositiveIntegerField()
referral_bonus = models.PositiveIntegerField(default=10)
min = models.DecimalField(max_digits=10, decimal_places=2)
max = models.DecimalField(max_digits=10, decimal_places=2)
duration = models.PositiveIntegerField()
Вот моя модель подписки
class Subscription(models.Model):
SUB_STATUS =(
('Pending', 'Pending'),
('Confirmed', 'Confirmed'),
('Expired', 'Expired')
)
user = models.OneToOneField(get_user_model(), on_delete=models.CASCADE, related_name="user")
type = models.CharField(max_length=10, default="Deposit", editable=False)
plan = models.ForeignKey(Plan, on_delete=models.DO_NOTHING, related_name="plan")
sub_method = models.CharField(max_length=24, choices=SUB_METHOD, default='Wallet')
sub_currency = models.CharField(max_length=12, choices=SUB_CURRENCY, default='Btc')
sub_amount = models.DecimalField(max_digits=1000, decimal_places=2, default=0.00)
expires_at = models.DateField(null=True, blank=True)
status = models.CharField(max_length=9, choices=SUB_STATUS, default="Pending")
verified_on = models.DateTimeField(blank=True, null=True)
active = models.BooleanField(default=False)
initiated_on = models.DateTimeField(auto_now_add=True)
ЛОГИКА, ВОЗНИКАЮЩАЯ, КОГДА АДМИНИСТРАТОР ПЕРЕКЛЮЧАЕТ АКТИВНОЕ ПОЛЕ
@receiver(post_save, sender=Subscription)
def activate_subcription(sender, instance, created, *args, **kwargs):
if instance.active == True:
user=instance.user
status = "Confirmed", verified_on = timezone.now()
expires_at = date.today() + timedelta(days=instance.plan.duration)
user.balance = F('balance') + instance.sub_amount
user.save()