feat: dodaj prefill email potpisa i body logging
Uvodi signature polje i default predlozak potpisa za nove korisnike, te data migraciju koja popunjava postojece prazne potpise. Email flow sada dosljedno dodaje korisnicki potpis i sprema finalni body poruke u dispatch log radi audita.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
17
backend/modules/fleet/email_utils.py
Normal file
17
backend/modules/fleet/email_utils.py
Normal file
@@ -0,0 +1,17 @@
|
||||
def append_user_signature(body, user):
|
||||
body_text = str(body or '').strip()
|
||||
if user is None:
|
||||
return body_text
|
||||
|
||||
signature = ''
|
||||
get_signature = getattr(user, 'get_email_signature', None)
|
||||
if callable(get_signature):
|
||||
signature = str(get_signature() or '').strip()
|
||||
else:
|
||||
signature = str(getattr(user, 'signature', '') or '').strip()
|
||||
|
||||
if not signature:
|
||||
return body_text
|
||||
if not body_text:
|
||||
return signature
|
||||
return f"{body_text}\n\n{signature}"
|
||||
@@ -29,6 +29,7 @@ from reportlab.lib.utils import ImageReader
|
||||
from reportlab.pdfgen import canvas
|
||||
from .models import VehicleNotification, GeneratedWorkOrderPdf
|
||||
from .pdf_layout import register_unicode_fonts, draw_standard_header_footer
|
||||
from .email_utils import append_user_signature
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
register_unicode_fonts()
|
||||
@@ -435,7 +436,7 @@ def send_work_order_email_bundle_task(
|
||||
|
||||
email_message = EmailMessage(
|
||||
subject=subject or f"Putni nalog {_work_order_display_code(work_order)}",
|
||||
body="\n".join(body_lines).strip(),
|
||||
body=append_user_signature("\n".join(body_lines).strip(), requested_by),
|
||||
from_email=from_email,
|
||||
to=recipients or [],
|
||||
)
|
||||
@@ -450,7 +451,8 @@ def send_work_order_email_bundle_task(
|
||||
}
|
||||
for filename, content, content_type in attachments
|
||||
]
|
||||
dispatch_log.save(update_fields=['attachments', 'updated_at'])
|
||||
dispatch_log.message = email_message.body
|
||||
dispatch_log.save(update_fields=['attachments', 'message', 'updated_at'])
|
||||
|
||||
try:
|
||||
email_message.send(fail_silently=False)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
from unittest.mock import patch
|
||||
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.core import mail
|
||||
from django.test import TestCase, override_settings
|
||||
|
||||
from modules.fleet.models import GeneratedWorkOrderPdf, Vehicle, VehicleNotification, WorkOrder
|
||||
@@ -58,3 +59,25 @@ class WorkOrderEmailTaskCachedPdfTests(TestCase):
|
||||
cached_pdfs = notif.metadata.get('cached_pdfs') if isinstance(notif.metadata, dict) else None
|
||||
self.assertTrue(isinstance(cached_pdfs, list) and len(cached_pdfs) > 0)
|
||||
self.assertIn('download_url', cached_pdfs[0])
|
||||
|
||||
def test_success_email_appends_requester_signature(self):
|
||||
mail.outbox.clear()
|
||||
|
||||
result = send_work_order_email_bundle_task(
|
||||
work_order_id=str(self.work_order.pk),
|
||||
requested_by_id=str(self.user.pk),
|
||||
recipients=['client@example.test'],
|
||||
message='Test poruka bez potpisa.',
|
||||
include_work_order_pdf=True,
|
||||
include_service_records_pdf=False,
|
||||
include_invoices_pdf=False,
|
||||
include_images=False,
|
||||
include_monthly_tasks=False,
|
||||
)
|
||||
|
||||
self.assertEqual(result.get('status'), 'ok')
|
||||
self.assertEqual(len(mail.outbox), 1)
|
||||
sent_body = mail.outbox[0].body
|
||||
self.assertIn('Test poruka bez potpisa.', sent_body)
|
||||
self.assertIn('S poštovanjem / Freundliche Grüße / Kind regards', sent_body)
|
||||
self.assertIn(self.user.email, sent_body)
|
||||
|
||||
@@ -30,6 +30,7 @@ from reportlab.lib.styles import getSampleStyleSheet
|
||||
from reportlab.pdfgen import canvas
|
||||
from reportlab.platypus import Table, TableStyle, Paragraph
|
||||
from .pdf_layout import register_unicode_fonts, draw_standard_header_footer
|
||||
from .email_utils import append_user_signature
|
||||
from rest_framework import viewsets, permissions, status, mixins
|
||||
from rest_framework.decorators import action, api_view, permission_classes
|
||||
from rest_framework.response import Response
|
||||
@@ -2203,10 +2204,11 @@ class VehicleServiceRecordViewSet(viewsets.ModelViewSet):
|
||||
body = _first_non_empty(request.data.get('message')) or (
|
||||
f"U prilogu je PDF servisnog zapisa. Poslano {timezone.now().strftime('%d.%m.%Y %H:%M')}."
|
||||
)
|
||||
body_with_signature = append_user_signature(body, request.user)
|
||||
_send_document_email(
|
||||
recipient=recipient,
|
||||
subject=subject,
|
||||
body=body,
|
||||
body=body_with_signature,
|
||||
filename=f"{service_record.pk}.service-record.pdf",
|
||||
pdf_bytes=pdf_bytes,
|
||||
)
|
||||
@@ -2216,7 +2218,7 @@ class VehicleServiceRecordViewSet(viewsets.ModelViewSet):
|
||||
service_record=service_record,
|
||||
recipients=[recipient],
|
||||
subject=subject,
|
||||
message=body,
|
||||
message=body_with_signature,
|
||||
attachments=[{'type': 'service_record_pdf', 'filename': f"{service_record.pk}.service-record.pdf"}],
|
||||
status='sent',
|
||||
sent_at=timezone.now(),
|
||||
|
||||
Reference in New Issue
Block a user