Fix: support ConsumableDocument in email attachments (#11196)

This commit is contained in:
shamoon
2025-10-27 10:37:57 -07:00
committed by GitHub
parent 701aafce06
commit 48d21da13b
2 changed files with 92 additions and 12 deletions

View File

@@ -7,6 +7,8 @@ from django.conf import settings
from django.core.mail import EmailMessage from django.core.mail import EmailMessage
from filelock import FileLock from filelock import FileLock
from documents.data_models import ConsumableDocument
if TYPE_CHECKING: if TYPE_CHECKING:
from documents.models import Document from documents.models import Document
@@ -15,7 +17,7 @@ def send_email(
subject: str, subject: str,
body: str, body: str,
to: list[str], to: list[str],
attachments: list[Document], attachments: list[Document | ConsumableDocument],
*, *,
use_archive: bool, use_archive: bool,
) -> int: ) -> int:
@@ -45,12 +47,15 @@ def send_email(
# Something could be renaming the file concurrently so it can't be attached # Something could be renaming the file concurrently so it can't be attached
with FileLock(settings.MEDIA_LOCK): with FileLock(settings.MEDIA_LOCK):
for document in attachments: for document in attachments:
if isinstance(document, ConsumableDocument):
attachment_path = document.original_file
friendly_filename = document.original_file.name
else:
attachment_path = ( attachment_path = (
document.archive_path document.archive_path
if use_archive and document.has_archive_version if use_archive and document.has_archive_version
else document.source_path else document.source_path
) )
friendly_filename = _get_unique_filename( friendly_filename = _get_unique_filename(
document, document,
used_filenames, used_filenames,

View File

@@ -30,6 +30,7 @@ from pytest_django.fixtures import SettingsWrapper
from documents import tasks from documents import tasks
from documents.data_models import ConsumableDocument from documents.data_models import ConsumableDocument
from documents.data_models import DocumentMetadataOverrides
from documents.data_models import DocumentSource from documents.data_models import DocumentSource
from documents.matching import document_matches_workflow from documents.matching import document_matches_workflow
from documents.matching import existing_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.assertEqual(doc.tags.all().count(), 1)
self.assertIn(self.t2, doc.tags.all()) 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( @override_settings(
PAPERLESS_EMAIL_HOST="localhost", PAPERLESS_EMAIL_HOST="localhost",
EMAIL_ENABLED=True, EMAIL_ENABLED=True,