This commit is contained in:
shamoon
2024-10-23 21:43:17 -07:00
parent 3cb3bad862
commit 2c05247d84
12 changed files with 106 additions and 116 deletions

View File

@@ -1,4 +1,4 @@
# Generated by Django 5.1.1 on 2024-10-24 04:03
# Generated by Django 5.1.1 on 2024-10-24 04:15
import django.db.models.deletion
import django.utils.timezone
@@ -14,29 +14,18 @@ class Migration(migrations.Migration):
operations = [
migrations.AddField(
model_name="workflowtrigger",
name="schedule_delay",
field=models.CharField(
blank=True,
help_text="The delay before the scheduled trigger is activated.",
max_length=256,
null=True,
verbose_name="schedule delay",
),
),
migrations.AddField(
model_name="workflowtrigger",
name="schedule_delay_custom_field",
name="schedule_date_custom_field",
field=models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.SET_NULL,
to="documents.customfield",
verbose_name="schedule delay custom field",
verbose_name="schedule date custom field",
),
),
migrations.AddField(
model_name="workflowtrigger",
name="schedule_delay_field",
name="schedule_date_field",
field=models.CharField(
choices=[
("added", "Added"),
@@ -45,9 +34,9 @@ class Migration(migrations.Migration):
("custom_field", "Custom Field"),
],
default="added",
help_text="The field to use for the delay.",
help_text="The field to check for a schedule trigger.",
max_length=20,
verbose_name="schedule delay field",
verbose_name="schedule date field",
),
),
migrations.AddField(
@@ -59,6 +48,15 @@ class Migration(migrations.Migration):
verbose_name="schedule is recurring",
),
),
migrations.AddField(
model_name="workflowtrigger",
name="schedule_offset_days",
field=models.PositiveIntegerField(
default=0,
help_text="The number of days to offset the schedule trigger by.",
verbose_name="schedule offset days",
),
),
migrations.AlterField(
model_name="workflowtrigger",
name="type",
@@ -85,6 +83,19 @@ class Migration(migrations.Migration):
verbose_name="ID",
),
),
(
"type",
models.PositiveIntegerField(
choices=[
(1, "Consumption Started"),
(2, "Document Added"),
(3, "Document Updated"),
(4, "Scheduled"),
],
null=True,
verbose_name="workflow trigger type",
),
),
(
"run_at",
models.DateTimeField(

View File

@@ -1023,7 +1023,7 @@ class WorkflowTrigger(models.Model):
API_UPLOAD = DocumentSource.ApiUpload.value, _("Api Upload")
MAIL_FETCH = DocumentSource.MailFetch.value, _("Mail Fetch")
class ScheduleDelayField(models.TextChoices):
class ScheduleDateField(models.TextChoices):
ADDED = "added", _("Added")
CREATED = "created", _("Created")
MODIFIED = "modified", _("Modified")
@@ -1105,13 +1105,11 @@ class WorkflowTrigger(models.Model):
verbose_name=_("has this correspondent"),
)
schedule_delay = models.CharField(
_("schedule delay"),
max_length=256,
null=True,
blank=True,
schedule_offset_days = models.PositiveIntegerField(
_("schedule offset days"),
default=0,
help_text=_(
"The delay before the scheduled trigger is activated.",
"The number of days to offset the schedule trigger by.",
),
)
@@ -1123,22 +1121,22 @@ class WorkflowTrigger(models.Model):
),
)
schedule_delay_field = models.CharField(
_("schedule delay field"),
schedule_date_field = models.CharField(
_("schedule date field"),
max_length=20,
choices=ScheduleDelayField.choices,
default=ScheduleDelayField.ADDED,
choices=ScheduleDateField.choices,
default=ScheduleDateField.ADDED,
help_text=_(
"The field to use for the delay.",
"The field to check for a schedule trigger.",
),
)
schedule_delay_custom_field = models.ForeignKey(
schedule_date_custom_field = models.ForeignKey(
CustomField,
null=True,
blank=True,
on_delete=models.SET_NULL,
verbose_name=_("schedule delay custom field"),
verbose_name=_("schedule date custom field"),
)
class Meta:
@@ -1401,6 +1399,12 @@ class WorkflowRun(models.Model):
verbose_name=_("workflow"),
)
type = models.PositiveIntegerField(
_("workflow trigger type"),
choices=WorkflowTrigger.WorkflowTriggerType.choices,
null=True,
)
document = models.ForeignKey(
Document,
null=True,

View File

@@ -21,7 +21,6 @@ from django.utils.crypto import get_random_string
from django.utils.text import slugify
from django.utils.translation import gettext as _
from drf_writable_nested.serializers import NestedUpdateMixin
from duration_parser import parse_timedelta
from guardian.core import ObjectPermissionChecker
from guardian.shortcuts import get_users_with_perms
from guardian.utils import get_group_obj_perms_model
@@ -1753,22 +1752,12 @@ class WorkflowTriggerSerializer(serializers.ModelSerializer):
"filter_has_tags",
"filter_has_correspondent",
"filter_has_document_type",
"schedule_delay",
"schedule_offset_days",
"schedule_is_recurring",
"schedule_delay_field",
"schedule_delay_custom_field",
"schedule_date_field",
"schedule_date_custom_field",
]
def validate_schedule_delay(self, value):
if value is not None:
try:
parse_timedelta(value)
except Exception as e:
raise serializers.ValidationError(
f"Invalid schedule delay format: {e}",
)
return value
def validate(self, attrs):
# Empty strings treated as None to avoid unexpected behavior
if (
@@ -1794,11 +1783,6 @@ class WorkflowTriggerSerializer(serializers.ModelSerializer):
"File name, path or mail rule filter are required",
)
if attrs["type"] == WorkflowTrigger.WorkflowTriggerType.SCHEDULED and (
"schedule_delay" not in attrs or attrs["schedule_delay"] is None
):
raise serializers.ValidationError("Schedule delay is required")
return attrs

View File

@@ -918,6 +918,7 @@ def run_workflows(
WorkflowRun.objects.create(
workflow=workflow,
type=trigger_type,
document=document if not use_overrides else None,
)

View File

@@ -14,7 +14,6 @@ from django.db import models
from django.db import transaction
from django.db.models.signals import post_save
from django.utils import timezone
from duration_parser import parse_timedelta
from filelock import FileLock
from whoosh.writing import AsyncWriter
@@ -342,38 +341,38 @@ def check_scheduled_workflows():
trigger: WorkflowTrigger
for trigger in schedule_triggers:
documents = Document.objects.none()
delay_td = parse_timedelta(trigger.schedule_delay)
offset_td = timedelta(days=trigger.schedule_offset_days)
logger.debug(
f"Checking trigger {trigger} with delay {delay_td} against field: {trigger.schedule_delay_field}",
f"Checking trigger {trigger} with offset {offset_td} against field: {trigger.schedule_date_field}",
)
if (
trigger.schedule_delay_field
== WorkflowTrigger.ScheduleDelayField.ADDED
trigger.schedule_date_field
== WorkflowTrigger.ScheduleDateField.ADDED
):
documents = Document.objects.filter(
added__lt=timezone.now() - delay_td,
added__lt=timezone.now() - offset_td,
)
elif (
trigger.schedule_delay_field
== WorkflowTrigger.ScheduleDelayField.CREATED
trigger.schedule_date_field
== WorkflowTrigger.ScheduleDateField.CREATED
):
documents = Document.objects.filter(
created__lt=timezone.now() - delay_td,
created__lt=timezone.now() - offset_td,
)
elif (
trigger.schedule_delay_field
== WorkflowTrigger.ScheduleDelayField.MODIFIED
trigger.schedule_date_field
== WorkflowTrigger.ScheduleDateField.MODIFIED
):
documents = Document.objects.filter(
modified__lt=timezone.now() - delay_td,
modified__lt=timezone.now() - offset_td,
)
elif (
trigger.schedule_delay_field
== WorkflowTrigger.ScheduleDelayField.CUSTOM_FIELD
trigger.schedule_date_field
== WorkflowTrigger.ScheduleDateField.CUSTOM_FIELD
):
cf_instances = CustomFieldInstance.objects.filter(
field=trigger.schedule_delay_custom_field,
value_date__lt=timezone.now() - delay_td,
field=trigger.schedule_date_custom_field,
value_date__lt=timezone.now() - offset_td,
)
documents = Document.objects.filter(
id__in=cf_instances.values_list("document", flat=True),
@@ -385,6 +384,7 @@ def check_scheduled_workflows():
for document in documents:
workflow_runs = WorkflowRun.objects.filter(
document=document,
type=WorkflowTrigger.WorkflowTriggerType.SCHEDULED,
workflow=workflow,
)
if not trigger.schedule_is_recurring and workflow_runs.exists():
@@ -396,7 +396,7 @@ def check_scheduled_workflows():
elif (
trigger.schedule_is_recurring
and workflow_runs.exists()
and workflow_runs.last().run_at > timezone.now() - delay_td
and workflow_runs.last().run_at > timezone.now() - offset_td
):
# schedule is recurring but the last run was within the delay
logger.debug(

View File

@@ -1318,8 +1318,8 @@ class TestWorkflows(DirectoriesMixin, FileSystemAssertsMixin, APITestCase):
"""
trigger = WorkflowTrigger.objects.create(
type=WorkflowTrigger.WorkflowTriggerType.SCHEDULED,
schedule_delay="1 day",
schedule_delay_field="created",
schedule_offset_days=1,
schedule_date_field="created",
)
action = WorkflowAction.objects.create(
assign_title="Doc assign owner",
@@ -1359,8 +1359,8 @@ class TestWorkflows(DirectoriesMixin, FileSystemAssertsMixin, APITestCase):
"""
trigger = WorkflowTrigger.objects.create(
type=WorkflowTrigger.WorkflowTriggerType.SCHEDULED,
schedule_delay="1 day",
schedule_delay_field=WorkflowTrigger.ScheduleDelayField.ADDED,
schedule_offset_days=1,
schedule_date_field=WorkflowTrigger.ScheduleDateField.ADDED,
)
action = WorkflowAction.objects.create(
assign_title="Doc assign owner",
@@ -1402,8 +1402,8 @@ class TestWorkflows(DirectoriesMixin, FileSystemAssertsMixin, APITestCase):
mock_filter.return_value = Document.objects.all()
trigger = WorkflowTrigger.objects.create(
type=WorkflowTrigger.WorkflowTriggerType.SCHEDULED,
schedule_delay="1 day",
schedule_delay_field=WorkflowTrigger.ScheduleDelayField.MODIFIED,
schedule_offset_days=1,
schedule_date_field=WorkflowTrigger.ScheduleDateField.MODIFIED,
)
action = WorkflowAction.objects.create(
assign_title="Doc assign owner",