]> git.ipfire.org Git - thirdparty/paperless-ngx.git/commitdiff
Fix: fix email/wh actions on consume started (#8750)
authorshamoon <4887959+shamoon@users.noreply.github.com>
Wed, 15 Jan 2025 15:48:10 +0000 (07:48 -0800)
committerGitHub <noreply@github.com>
Wed, 15 Jan 2025 15:48:10 +0000 (15:48 +0000)
src/documents/consumer.py
src/documents/signals/handlers.py
src/documents/tests/test_workflows.py

index ec07c63a8f4d921489aeae3f35a3d7303b4250d5..ec92ddba88663f3a7457628ef22bd48d5dd07f9a 100644 (file)
@@ -62,10 +62,10 @@ class WorkflowTriggerPlugin(
         Get overrides from matching workflows
         """
         overrides, msg = run_workflows(
-            WorkflowTrigger.WorkflowTriggerType.CONSUMPTION,
-            self.input_doc,
-            None,
-            DocumentMetadataOverrides(),
+            trigger_type=WorkflowTrigger.WorkflowTriggerType.CONSUMPTION,
+            document=self.input_doc,
+            logging_group=None,
+            overrides=DocumentMetadataOverrides(),
         )
         if overrides:
             self.metadata.update(overrides)
index efba1e41ce27f4ec61b296b1cd9092af33e695ae..08fd8d00f16241df05e3f4f2c8699b39e4d16dc3 100644 (file)
@@ -11,6 +11,7 @@ from celery.signals import task_failure
 from celery.signals import task_postrun
 from celery.signals import task_prerun
 from django.conf import settings
+from django.contrib.auth.models import User
 from django.core.mail import EmailMessage
 from django.db import DatabaseError
 from django.db import close_old_connections
@@ -29,9 +30,11 @@ from documents.data_models import DocumentMetadataOverrides
 from documents.file_handling import create_source_path_directory
 from documents.file_handling import delete_empty_directories
 from documents.file_handling import generate_unique_filename
+from documents.models import Correspondent
 from documents.models import CustomField
 from documents.models import CustomFieldInstance
 from documents.models import Document
+from documents.models import DocumentType
 from documents.models import MatchingModel
 from documents.models import PaperlessTask
 from documents.models import Tag
@@ -907,21 +910,43 @@ def run_workflows(
             )
             return
 
-        title = (
-            document.title
-            if isinstance(document, Document)
-            else str(document.original_file)
-        )
-        doc_url = None
-        if isinstance(document, Document):
+        if not use_overrides:
+            title = document.title
             doc_url = f"{settings.PAPERLESS_URL}/documents/{document.pk}/"
-        correspondent = document.correspondent.name if document.correspondent else ""
-        document_type = document.document_type.name if document.document_type else ""
-        owner_username = document.owner.username if document.owner else ""
-        filename = document.original_filename or ""
-        current_filename = document.filename or ""
-        added = timezone.localtime(document.added)
-        created = timezone.localtime(document.created)
+            correspondent = (
+                document.correspondent.name if document.correspondent else ""
+            )
+            document_type = (
+                document.document_type.name if document.document_type else ""
+            )
+            owner_username = document.owner.username if document.owner else ""
+            filename = document.original_filename or ""
+            current_filename = document.filename or ""
+            added = timezone.localtime(document.added)
+            created = timezone.localtime(document.created)
+        else:
+            title = overrides.title if overrides.title else str(document.original_file)
+            doc_url = ""
+            correspondent = (
+                Correspondent.objects.filter(pk=overrides.correspondent_id).first()
+                if overrides.correspondent_id
+                else ""
+            )
+            document_type = (
+                DocumentType.objects.filter(pk=overrides.document_type_id).first().name
+                if overrides.document_type_id
+                else ""
+            )
+            owner_username = (
+                User.objects.filter(pk=overrides.owner_id).first().username
+                if overrides.owner_id
+                else ""
+            )
+            filename = document.original_file if document.original_file else ""
+            current_filename = filename
+            added = timezone.localtime(timezone.now())
+            created = timezone.localtime(overrides.created)
+
         subject = parse_w_workflow_placeholders(
             action.email.subject,
             correspondent,
@@ -973,21 +998,42 @@ def run_workflows(
             )
 
     def webhook_action():
-        title = (
-            document.title
-            if isinstance(document, Document)
-            else str(document.original_file)
-        )
-        doc_url = None
-        if isinstance(document, Document):
+        if not use_overrides:
+            title = document.title
             doc_url = f"{settings.PAPERLESS_URL}/documents/{document.pk}/"
-        correspondent = document.correspondent.name if document.correspondent else ""
-        document_type = document.document_type.name if document.document_type else ""
-        owner_username = document.owner.username if document.owner else ""
-        filename = document.original_filename or ""
-        current_filename = document.filename or ""
-        added = timezone.localtime(document.added)
-        created = timezone.localtime(document.created)
+            correspondent = (
+                document.correspondent.name if document.correspondent else ""
+            )
+            document_type = (
+                document.document_type.name if document.document_type else ""
+            )
+            owner_username = document.owner.username if document.owner else ""
+            filename = document.original_filename or ""
+            current_filename = document.filename or ""
+            added = timezone.localtime(document.added)
+            created = timezone.localtime(document.created)
+        else:
+            title = overrides.title if overrides.title else str(document.original_file)
+            doc_url = ""
+            correspondent = (
+                Correspondent.objects.filter(pk=overrides.correspondent_id).first()
+                if overrides.correspondent_id
+                else ""
+            )
+            document_type = (
+                DocumentType.objects.filter(pk=overrides.document_type_id).first().name
+                if overrides.document_type_id
+                else ""
+            )
+            owner_username = (
+                User.objects.filter(pk=overrides.owner_id).first().username
+                if overrides.owner_id
+                else ""
+            )
+            filename = document.original_file if document.original_file else ""
+            current_filename = filename
+            added = timezone.localtime(timezone.now())
+            created = timezone.localtime(overrides.created)
 
         try:
             data = {}
index 972485d3462e1babc9b3c84899059b997e62c00d..9f976bbfe49984fac1242996a3aa3caf9e674f61 100644 (file)
@@ -2296,6 +2296,64 @@ class TestWorkflows(
         EMAIL_ENABLED=True,
         PAPERLESS_URL="http://localhost:8000",
     )
+    @mock.patch("httpx.post")
+    @mock.patch("django.core.mail.message.EmailMessage.send")
+    def test_workflow_email_consumption_started(self, mock_email_send, mock_post):
+        """
+        GIVEN:
+            - Workflow with email action and consumption trigger
+        WHEN:
+            - Document is consumed
+        THEN:
+            - Email is sent
+        """
+        mock_post.return_value = mock.Mock(
+            status_code=200,
+            json=mock.Mock(return_value={"status": "ok"}),
+        )
+        mock_email_send.return_value = 1
+
+        trigger = WorkflowTrigger.objects.create(
+            type=WorkflowTrigger.WorkflowTriggerType.CONSUMPTION,
+        )
+        email_action = WorkflowActionEmail.objects.create(
+            subject="Test Notification: {doc_title}",
+            body="Test message: {doc_url}",
+            to="user@example.com",
+            include_document=False,
+        )
+        action = WorkflowAction.objects.create(
+            type=WorkflowAction.WorkflowActionType.EMAIL,
+            email=email_action,
+        )
+        w = Workflow.objects.create(
+            name="Workflow 1",
+            order=0,
+        )
+        w.triggers.add(trigger)
+        w.actions.add(action)
+        w.save()
+
+        test_file = shutil.copy(
+            self.SAMPLE_DIR / "simple.pdf",
+            self.dirs.scratch_dir / "simple.pdf",
+        )
+
+        with mock.patch("documents.tasks.ProgressManager", DummyProgressManager):
+            with self.assertLogs("paperless.matching", level="INFO"):
+                tasks.consume_file(
+                    ConsumableDocument(
+                        source=DocumentSource.ConsumeFolder,
+                        original_file=test_file,
+                    ),
+                    None,
+                )
+
+        mock_email_send.assert_called_once()
+
+    @override_settings(
+        PAPERLESS_URL="http://localhost:8000",
+    )
     @mock.patch("documents.signals.handlers.send_webhook.delay")
     def test_workflow_webhook_action_body(self, mock_post):
         """
@@ -2352,8 +2410,6 @@ class TestWorkflows(
         )
 
     @override_settings(
-        PAPERLESS_EMAIL_HOST="localhost",
-        EMAIL_ENABLED=True,
         PAPERLESS_URL="http://localhost:8000",
     )
     @mock.patch("documents.signals.handlers.send_webhook.delay")
@@ -2415,8 +2471,6 @@ class TestWorkflows(
         )
 
     @override_settings(
-        PAPERLESS_EMAIL_HOST="localhost",
-        EMAIL_ENABLED=True,
         PAPERLESS_URL="http://localhost:8000",
     )
     def test_workflow_webhook_action_fail(self):
@@ -2562,3 +2616,56 @@ class TestWorkflows(
                     "Failed attempt sending webhook to http://paperless-ngx.com"
                 )
                 self.assertIn(expected_str, cm.output[0])
+
+    @mock.patch("documents.signals.handlers.send_webhook.delay")
+    def test_workflow_webhook_action_consumption(self, mock_post):
+        """
+        GIVEN:
+            - Workflow with webhook action and consumption trigger
+        WHEN:
+            - Document is consumed
+        THEN:
+            - Webhook is sent
+        """
+        mock_post.return_value = mock.Mock(
+            status_code=200,
+            json=mock.Mock(return_value={"status": "ok"}),
+        )
+
+        trigger = WorkflowTrigger.objects.create(
+            type=WorkflowTrigger.WorkflowTriggerType.CONSUMPTION,
+        )
+        webhook_action = WorkflowActionWebhook.objects.create(
+            use_params=False,
+            body="Test message: {doc_url}",
+            url="http://paperless-ngx.com",
+            include_document=False,
+        )
+        action = WorkflowAction.objects.create(
+            type=WorkflowAction.WorkflowActionType.WEBHOOK,
+            webhook=webhook_action,
+        )
+        w = Workflow.objects.create(
+            name="Workflow 1",
+            order=0,
+        )
+        w.triggers.add(trigger)
+        w.actions.add(action)
+        w.save()
+
+        test_file = shutil.copy(
+            self.SAMPLE_DIR / "simple.pdf",
+            self.dirs.scratch_dir / "simple.pdf",
+        )
+
+        with mock.patch("documents.tasks.ProgressManager", DummyProgressManager):
+            with self.assertLogs("paperless.matching", level="INFO"):
+                tasks.consume_file(
+                    ConsumableDocument(
+                        source=DocumentSource.ConsumeFolder,
+                        original_file=test_file,
+                    ),
+                    None,
+                )
+
+        mock_post.assert_called_once()