]> git.ipfire.org Git - thirdparty/paperless-ngx.git/commitdiff
Fix: support ConsumableDocument in email attachments (#11196)
authorshamoon <4887959+shamoon@users.noreply.github.com>
Mon, 27 Oct 2025 17:37:57 +0000 (10:37 -0700)
committerGitHub <noreply@github.com>
Mon, 27 Oct 2025 17:37:57 +0000 (10:37 -0700)
src/documents/mail.py
src/documents/tests/test_workflows.py

index 240b41e1839e326b48648383fa0633a0ea1e853d..6af48ca9b3c250994a1089ec27229e96d41cc03b 100644 (file)
@@ -7,6 +7,8 @@ from django.conf import settings
 from django.core.mail import EmailMessage
 from filelock import FileLock
 
+from documents.data_models import ConsumableDocument
+
 if TYPE_CHECKING:
     from documents.models import Document
 
@@ -15,7 +17,7 @@ def send_email(
     subject: str,
     body: str,
     to: list[str],
-    attachments: list[Document],
+    attachments: list[Document | ConsumableDocument],
     *,
     use_archive: bool,
 ) -> int:
@@ -45,17 +47,20 @@ def send_email(
     # Something could be renaming the file concurrently so it can't be attached
     with FileLock(settings.MEDIA_LOCK):
         for document in attachments:
-            attachment_path = (
-                document.archive_path
-                if use_archive and document.has_archive_version
-                else document.source_path
-            )
-
-            friendly_filename = _get_unique_filename(
-                document,
-                used_filenames,
-                archive=use_archive and document.has_archive_version,
-            )
+            if isinstance(document, ConsumableDocument):
+                attachment_path = document.original_file
+                friendly_filename = document.original_file.name
+            else:
+                attachment_path = (
+                    document.archive_path
+                    if use_archive and document.has_archive_version
+                    else document.source_path
+                )
+                friendly_filename = _get_unique_filename(
+                    document,
+                    used_filenames,
+                    archive=use_archive and document.has_archive_version,
+                )
             used_filenames.add(friendly_filename)
 
             with attachment_path.open("rb") as f:
index a6da01578cfe61cf0a93829788e8b95c6efe34a1..c25565ae6255ee7cad8e180e0524e3f494271630 100644 (file)
@@ -30,6 +30,7 @@ from pytest_django.fixtures import SettingsWrapper
 
 from documents import tasks
 from documents.data_models import ConsumableDocument
+from documents.data_models import DocumentMetadataOverrides
 from documents.data_models import DocumentSource
 from documents.matching import document_matches_workflow
 from documents.matching import existing_document_matches_workflow
@@ -2788,6 +2789,80 @@ class TestWorkflows(
         self.assertEqual(doc.tags.all().count(), 1)
         self.assertIn(self.t2, doc.tags.all())
 
+    @override_settings(
+        PAPERLESS_EMAIL_HOST="localhost",
+        EMAIL_ENABLED=True,
+        PAPERLESS_URL="http://localhost:8000",
+    )
+    @mock.patch("django.core.mail.message.EmailMessage.send")
+    def test_workflow_assignment_then_email_includes_attachment(self, mock_email_send):
+        """
+        GIVEN:
+            - Workflow with assignment and email actions
+            - Email action configured to include the document
+        WHEN:
+            - Workflow is run on a newly created document
+        THEN:
+            - Email action sends the document as an attachment
+        """
+
+        storage_path = StoragePath.objects.create(
+            name="sp2",
+            path="workflow/{{ document.pk }}",
+        )
+        trigger = WorkflowTrigger.objects.create(
+            type=WorkflowTrigger.WorkflowTriggerType.CONSUMPTION,
+        )
+        assignment_action = WorkflowAction.objects.create(
+            type=WorkflowAction.WorkflowActionType.ASSIGNMENT,
+            assign_storage_path=storage_path,
+            assign_owner=self.user2,
+        )
+        assignment_action.assign_tags.add(self.t1)
+
+        email_action_config = WorkflowActionEmail.objects.create(
+            subject="Doc ready {doc_title}",
+            body="Document URL: {doc_url}",
+            to="owner@example.com",
+            include_document=True,
+        )
+        email_action = WorkflowAction.objects.create(
+            type=WorkflowAction.WorkflowActionType.EMAIL,
+            email=email_action_config,
+        )
+
+        workflow = Workflow.objects.create(name="Assignment then email", order=0)
+        workflow.triggers.add(trigger)
+        workflow.actions.set([assignment_action, email_action])
+
+        temp_working_copy = shutil.copy(
+            self.SAMPLE_DIR / "simple.pdf",
+            self.dirs.scratch_dir / "working-copy.pdf",
+        )
+
+        Document.objects.create(
+            title="workflow doc",
+            correspondent=self.c,
+            checksum="wf-assignment-email",
+            mime_type="application/pdf",
+        )
+
+        consumable_document = ConsumableDocument(
+            source=DocumentSource.ConsumeFolder,
+            original_file=temp_working_copy,
+        )
+
+        mock_email_send.return_value = 1
+
+        with self.assertNoLogs("paperless.handlers", level="ERROR"):
+            run_workflows(
+                WorkflowTrigger.WorkflowTriggerType.CONSUMPTION,
+                consumable_document,
+                overrides=DocumentMetadataOverrides(),
+            )
+
+        mock_email_send.assert_called_once()
+
     @override_settings(
         PAPERLESS_EMAIL_HOST="localhost",
         EMAIL_ENABLED=True,