Browse Source

scedule and repeatable task type logic splitted

master
Mohsen Taba 1 week ago
parent
commit
358f481708
  1. 23
      apps/account/migrations/0010_schedulednotification_scheduled_time_and_more.py
  2. 31
      apps/account/models/notification.py
  3. 2
      apps/account/serializers/notification.py
  4. 4
      apps/account/tasks.py

23
apps/account/migrations/0010_schedulednotification_scheduled_time_and_more.py

@ -0,0 +1,23 @@
# Generated by Django 4.2.30 on 2026-07-12 10:58
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('account', '0009_schedulednotification_body_en_and_more'),
]
operations = [
migrations.AddField(
model_name='schedulednotification',
name='scheduled_time',
field=models.DateTimeField(blank=True, null=True, verbose_name='scheduled time'),
),
migrations.AlterField(
model_name='schedulednotification',
name='schedule_type',
field=models.CharField(choices=[('do_not_repeat', 'Do Not Repeat'), ('daily', 'Daily'), ('weekly', 'Weekly'), ('monthly', 'Monthly'), ('cron', 'Custom Cron Expression')], default='do_not_repeat', max_length=20, verbose_name='schedule type'),
),
]

31
apps/account/models/notification.py

@ -58,6 +58,7 @@ class ScheduledNotification(models.Model):
ALL_PROFESSORS = 'all_professors', _('All Professors')
class ScheduleTypeChoices(models.TextChoices):
DO_NOT_REPEAT = 'do_not_repeat', _('Do Not Repeat')
DAILY = 'daily', _('Daily')
WEEKLY = 'weekly', _('Weekly')
MONTHLY = 'monthly', _('Monthly')
@ -76,7 +77,8 @@ class ScheduledNotification(models.Model):
is_active = models.BooleanField(default=True, verbose_name=_('is active'))
schedule_type = models.CharField(max_length=20, choices=ScheduleTypeChoices.choices, default=ScheduleTypeChoices.DAILY, verbose_name=_('schedule type'))
schedule_type = models.CharField(max_length=20, choices=ScheduleTypeChoices.choices, default=ScheduleTypeChoices.DO_NOT_REPEAT, verbose_name=_('schedule type'))
scheduled_time = models.DateTimeField(null=True, blank=True, verbose_name=_('scheduled time'))
time_of_day = models.TimeField(default="09:00:00", verbose_name=_('time of day'))
days_of_week = models.CharField(max_length=50, blank=True, null=True, help_text=_('Comma-separated days (1 for Mon, 6 for Sat, 0 for Sun). E.g. "6,0" for Sat and Sun.'), verbose_name=_('days of week'))
@ -99,10 +101,31 @@ class ScheduledNotification(models.Model):
return self.name
def save(self, *args, **kwargs):
from django_celery_beat.models import CrontabSchedule, PeriodicTask
from django_celery_beat.models import CrontabSchedule, ClockedSchedule, PeriodicTask
import json
from django.conf import settings
schedule = None
clocked = None
one_off = False
if self.schedule_type == self.ScheduleTypeChoices.DO_NOT_REPEAT:
if self.scheduled_time:
clocked, _ = ClockedSchedule.objects.get_or_create(
clocked_time=self.scheduled_time
)
one_off = True
else:
if self.periodic_task:
task = self.periodic_task
self.periodic_task = None
super().save(*args, **kwargs)
task.delete()
return
else:
super().save(*args, **kwargs)
return
else:
# Calculate cron fields based on schedule_type
minute = str(self.time_of_day.minute)
hour = str(self.time_of_day.hour)
@ -140,6 +163,8 @@ class ScheduledNotification(models.Model):
task = self.periodic_task
task.name = task_name
task.crontab = schedule
task.clocked = clocked
task.one_off = one_off
task.enabled = self.is_active
task.kwargs = task_kwargs
task.save()
@ -148,6 +173,8 @@ class ScheduledNotification(models.Model):
name=task_name,
task='apps.account.tasks.run_scheduled_notification_task',
crontab=schedule,
clocked=clocked,
one_off=one_off,
enabled=self.is_active,
kwargs=task_kwargs
)

2
apps/account/serializers/notification.py

@ -56,5 +56,5 @@ class AdminScheduledNotificationSerializer(serializers.ModelSerializer):
'id', 'name', 'template', 'template_name', 'target_group', 'send_to_all',
'user', 'user_fullname', 'user_email', 'title_ru', 'title_en',
'body_ru', 'body_en', 'is_active', 'schedule_type', 'time_of_day',
'days_of_week', 'days_of_month', 'custom_cron'
'days_of_week', 'days_of_month', 'custom_cron', 'scheduled_time'
]

4
apps/account/tasks.py

@ -457,6 +457,10 @@ def run_scheduled_notification_task(campaign_id):
notification_type=notification_type
)
if campaign.schedule_type == 'do_not_repeat':
campaign.is_active = False
campaign.save()

Loading…
Cancel
Save