diff --git a/src/documents/tasks.py b/src/documents/tasks.py index 13c104185..b793f9437 100644 --- a/src/documents/tasks.py +++ b/src/documents/tasks.py @@ -387,6 +387,18 @@ def empty_trash(doc_ids=None): @shared_task def check_scheduled_workflows(): + """ + Check and run all enabled scheduled workflows. + + Scheduled triggers are evaluated based on a target date field (e.g. added, created, modified, or a custom date field), + combined with a day offset. + + The offset is mathematically negated resulting in the following behavior: + - Positive offsets mean the workflow should trigger BEFORE the specified date (e.g., offset = +7 → trigger 7 days before) + - Negative offsets mean the workflow should trigger AFTER the specified date (e.g., offset = -7 → trigger 7 days after) + + Once a document satisfies this condition, and recurring/non-recurring constraints are met, the workflow is run. + """ scheduled_workflows: list[Workflow] = ( Workflow.objects.filter( triggers__type=WorkflowTrigger.WorkflowTriggerType.SCHEDULED, diff --git a/src/documents/tests/test_workflows.py b/src/documents/tests/test_workflows.py index 17464b973..51ea2be23 100644 --- a/src/documents/tests/test_workflows.py +++ b/src/documents/tests/test_workflows.py @@ -1610,7 +1610,7 @@ class TestWorkflows( doc.refresh_from_db() self.assertIsNone(doc.owner) - def test_workflow_scheduled_trigger_negative_offset(self): + def test_workflow_scheduled_trigger_negative_offset_customfield(self): """ GIVEN: - Existing workflow with SCHEDULED trigger and negative offset of -7 days (so 7 days after date) @@ -1662,6 +1662,55 @@ class TestWorkflows( doc.refresh_from_db() self.assertEqual(doc.owner, self.user2) + def test_workflow_scheduled_trigger_negative_offset_created(self): + """ + GIVEN: + - Existing workflow with SCHEDULED trigger and negative offset of -7 days (so 7 days after date) + - Created date set to 8 days ago → trigger time = 1 day ago and 5 days ago + WHEN: + - Scheduled workflows are checked for document + THEN: + - Workflow runs and document owner is updated for the first document, not the second + """ + trigger = WorkflowTrigger.objects.create( + type=WorkflowTrigger.WorkflowTriggerType.SCHEDULED, + schedule_offset_days=-7, + schedule_date_field=WorkflowTrigger.ScheduleDateField.CREATED, + ) + action = WorkflowAction.objects.create( + assign_title="Doc assign owner", + assign_owner=self.user2, + ) + w = Workflow.objects.create( + name="Workflow 1", + order=0, + ) + w.triggers.add(trigger) + w.actions.add(action) + w.save() + + doc = Document.objects.create( + title="sample test", + correspondent=self.c, + original_filename="sample.pdf", + checksum="1", + created=timezone.now().date() - timedelta(days=8), + ) + + doc2 = Document.objects.create( + title="sample test 2", + correspondent=self.c, + original_filename="sample2.pdf", + checksum="2", + created=timezone.now().date() - timedelta(days=5), + ) + + tasks.check_scheduled_workflows() + doc.refresh_from_db() + self.assertEqual(doc.owner, self.user2) + doc2.refresh_from_db() + self.assertIsNone(doc2.owner) # has not triggered yet + def test_workflow_enabled_disabled(self): trigger = WorkflowTrigger.objects.create( type=WorkflowTrigger.WorkflowTriggerType.DOCUMENT_ADDED,