diff --git a/app/modules/sag/backend/router.py b/app/modules/sag/backend/router.py index 4c5ec2e..3f47f80 100644 --- a/app/modules/sag/backend/router.py +++ b/app/modules/sag/backend/router.py @@ -122,6 +122,8 @@ class SagSendEmailRequest(BaseModel): bcc: List[str] = Field(default_factory=list) body_html: Optional[str] = None attachment_file_ids: List[int] = Field(default_factory=list) + thread_email_id: Optional[int] = None + thread_key: Optional[str] = None def _normalize_email_list(values: List[str], field_name: str) -> List[str]: @@ -2199,6 +2201,42 @@ async def send_sag_email(sag_id: int, payload: SagSendEmailRequest): "file_path": str(path), }) + in_reply_to_header = None + references_header = None + if payload.thread_email_id: + thread_row = None + try: + thread_row = execute_query_single( + """ + SELECT id, message_id, in_reply_to, email_references + FROM email_messages + WHERE id = %s + """, + (payload.thread_email_id,), + ) + except Exception: + # Backward compatibility for DBs without in_reply_to/email_references columns. + thread_row = execute_query_single( + """ + SELECT id, message_id + FROM email_messages + WHERE id = %s + """, + (payload.thread_email_id,), + ) + if thread_row: + base_message_id = str(thread_row.get("message_id") or "").strip() + if base_message_id and not base_message_id.startswith("<"): + base_message_id = f"<{base_message_id}>" + if base_message_id: + in_reply_to_header = base_message_id + + existing_refs = str(thread_row.get("email_references") or "").strip() + if existing_refs: + references_header = f"{existing_refs} {base_message_id}".strip() + else: + references_header = base_message_id + email_service = EmailService() success, send_message, generated_message_id = await email_service.send_email_with_attachments( to_addresses=to_addresses, @@ -2207,6 +2245,8 @@ async def send_sag_email(sag_id: int, payload: SagSendEmailRequest): body_html=payload.body_html, cc=cc_addresses, bcc=bcc_addresses, + in_reply_to=in_reply_to_header, + references=references_header, attachments=smtp_attachments, respect_dry_run=False, ) @@ -2218,36 +2258,72 @@ async def send_sag_email(sag_id: int, payload: SagSendEmailRequest): sender_name = settings.EMAIL_SMTP_FROM_NAME or "BMC Hub" sender_email = settings.EMAIL_SMTP_FROM_ADDRESS or "" - insert_email_query = """ - INSERT INTO email_messages ( - message_id, subject, sender_email, sender_name, - recipient_email, cc, body_text, body_html, - received_date, folder, has_attachments, attachment_count, - status, import_method, linked_case_id + insert_result = None + try: + insert_email_query = """ + INSERT INTO email_messages ( + message_id, subject, sender_email, sender_name, + recipient_email, cc, body_text, body_html, + in_reply_to, email_references, + received_date, folder, has_attachments, attachment_count, + status, import_method, linked_case_id + ) + VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s) + RETURNING id + """ + insert_result = execute_query( + insert_email_query, + ( + generated_message_id, + subject, + sender_email, + sender_name, + ", ".join(to_addresses), + ", ".join(cc_addresses), + body_text, + payload.body_html, + in_reply_to_header, + references_header, + datetime.now(), + "Sent", + bool(smtp_attachments), + len(smtp_attachments), + "sent", + "sag_outbound", + sag_id, + ), + ) + except Exception: + insert_email_query = """ + INSERT INTO email_messages ( + message_id, subject, sender_email, sender_name, + recipient_email, cc, body_text, body_html, + received_date, folder, has_attachments, attachment_count, + status, import_method, linked_case_id + ) + VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s) + RETURNING id + """ + insert_result = execute_query( + insert_email_query, + ( + generated_message_id, + subject, + sender_email, + sender_name, + ", ".join(to_addresses), + ", ".join(cc_addresses), + body_text, + payload.body_html, + datetime.now(), + "Sent", + bool(smtp_attachments), + len(smtp_attachments), + "sent", + "sag_outbound", + sag_id, + ), ) - VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s) - RETURNING id - """ - insert_result = execute_query( - insert_email_query, - ( - generated_message_id, - subject, - sender_email, - sender_name, - ", ".join(to_addresses), - ", ".join(cc_addresses), - body_text, - payload.body_html, - datetime.now(), - "Sent", - bool(smtp_attachments), - len(smtp_attachments), - "sent", - "sag_outbound", - sag_id, - ), - ) if not insert_result: logger.error("❌ Email sent but outbound log insert failed for case %s", sag_id) @@ -2286,9 +2362,11 @@ async def send_sag_email(sag_id: int, payload: SagSendEmailRequest): ) logger.info( - "✅ Outbound case email sent and linked (case=%s, email_id=%s, recipients=%s)", + "✅ Outbound case email sent and linked (case=%s, email_id=%s, thread_email_id=%s, thread_key=%s, recipients=%s)", sag_id, email_id, + payload.thread_email_id, + payload.thread_key, ", ".join(to_addresses), ) return { diff --git a/app/modules/sag/templates/detail.html b/app/modules/sag/templates/detail.html index 43d2625..e46576f 100644 --- a/app/modules/sag/templates/detail.html +++ b/app/modules/sag/templates/detail.html @@ -3590,6 +3590,9 @@
E-mail på sagen
+
-
-
-
-
- - -
-
- - -
-
- - -
-
-
-
- - -
-
- - -
-
-
- - -
-
- - -
-
-
@@ -3687,6 +3652,58 @@
+ +