Add machine relationship to operator report email alerts
- Query AssetRelationship to find if PC has a machine relationship - Subject line now shows: "Operator Issue Report: HOSTNAME (Machine #6906)" - Email body includes machine name and number as clickable link - Machine info only appears if relationship exists
This commit is contained in:
@@ -2941,6 +2941,7 @@ def _send_operator_report_alert(report, asset_id, hostname):
|
|||||||
"""Send email alert for new operator issue report to default alert recipients."""
|
"""Send email alert for new operator issue report to default alert recipients."""
|
||||||
from flask import url_for, request
|
from flask import url_for, request
|
||||||
from shopdb.utils.mailer import get_smtp_config, _normalize_recipients
|
from shopdb.utils.mailer import get_smtp_config, _normalize_recipients
|
||||||
|
from shopdb.core.models.relationship import AssetRelationship
|
||||||
|
|
||||||
current_app.logger.info('_send_operator_report_alert called for report %d, asset %d, hostname %s',
|
current_app.logger.info('_send_operator_report_alert called for report %d, asset %d, hostname %s',
|
||||||
report.operatorreportid, asset_id, hostname)
|
report.operatorreportid, asset_id, hostname)
|
||||||
@@ -2960,6 +2961,24 @@ def _send_operator_report_alert(report, asset_id, hostname):
|
|||||||
current_app.logger.warning('Cannot send operator report alert: asset %d not found', asset_id)
|
current_app.logger.warning('Cannot send operator report alert: asset %d not found', asset_id)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
# Check if this PC has a relationship to a machine
|
||||||
|
machine_relationship = (
|
||||||
|
AssetRelationship.query
|
||||||
|
.filter_by(sourceassetid=asset_id)
|
||||||
|
.filter(AssetRelationship.label.like('%machine%'))
|
||||||
|
.first()
|
||||||
|
)
|
||||||
|
|
||||||
|
machine_info = None
|
||||||
|
if machine_relationship:
|
||||||
|
machine_asset = Asset.query.get(machine_relationship.targetassetid)
|
||||||
|
if machine_asset:
|
||||||
|
machine_info = {
|
||||||
|
'assetid': machine_asset.assetid,
|
||||||
|
'assetnumber': machine_asset.assetnumber,
|
||||||
|
'name': machine_asset.name
|
||||||
|
}
|
||||||
|
|
||||||
# Generate absolute URL to frontend page (not API endpoint)
|
# Generate absolute URL to frontend page (not API endpoint)
|
||||||
try:
|
try:
|
||||||
scheme = request.scheme if request else 'https'
|
scheme = request.scheme if request else 'https'
|
||||||
@@ -2988,6 +3007,22 @@ def _send_operator_report_alert(report, asset_id, hostname):
|
|||||||
safe_reason = escape(report.reason)
|
safe_reason = escape(report.reason)
|
||||||
safe_details = escape(report.details or 'No additional details provided.')
|
safe_details = escape(report.details or 'No additional details provided.')
|
||||||
|
|
||||||
|
# Build machine info for subject and body
|
||||||
|
machine_subject_part = ''
|
||||||
|
machine_body_line = ''
|
||||||
|
if machine_info:
|
||||||
|
safe_machine_number = escape(machine_info['assetnumber'] or 'N/A')
|
||||||
|
safe_machine_name = escape(machine_info['name'] or safe_machine_number)
|
||||||
|
try:
|
||||||
|
scheme = request.scheme if request else 'https'
|
||||||
|
host = request.host if request else 'localhost'
|
||||||
|
machine_url = f'{scheme}://{host}/shopdb/machines/{machine_info["assetid"]}'
|
||||||
|
except Exception:
|
||||||
|
machine_url = f'https://localhost/shopdb/machines/{machine_info["assetid"]}'
|
||||||
|
|
||||||
|
machine_subject_part = f' (Machine #{safe_machine_number})'
|
||||||
|
machine_body_line = f'<p style="margin: 0;"><strong>Machine:</strong> <a href="{escape(machine_url)}">{safe_machine_name}</a> (#{safe_machine_number})</p>'
|
||||||
|
|
||||||
# Build HTML body (don't use render_email to avoid subject duplication)
|
# Build HTML body (don't use render_email to avoid subject duplication)
|
||||||
html_body = f'''
|
html_body = f'''
|
||||||
<div style="font-family:Arial,Helvetica,sans-serif;max-width:640px;margin:0 auto;color:#222;">
|
<div style="font-family:Arial,Helvetica,sans-serif;max-width:640px;margin:0 auto;color:#222;">
|
||||||
@@ -2996,6 +3031,7 @@ def _send_operator_report_alert(report, asset_id, hostname):
|
|||||||
<p style="margin: 0 0 8px; font-weight: bold; color: #d93f3f;">New Issue Report from Shop Floor</p>
|
<p style="margin: 0 0 8px; font-weight: bold; color: #d93f3f;">New Issue Report from Shop Floor</p>
|
||||||
<p style="margin: 0;"><strong>Device:</strong> <a href="{escape(device_url)}">{safe_name}</a> ({safe_hostname})</p>
|
<p style="margin: 0;"><strong>Device:</strong> <a href="{escape(device_url)}">{safe_name}</a> ({safe_hostname})</p>
|
||||||
<p style="margin: 0;"><strong>Asset Number:</strong> <a href="{escape(device_url)}">{safe_assetnumber}</a></p>
|
<p style="margin: 0;"><strong>Asset Number:</strong> <a href="{escape(device_url)}">{safe_assetnumber}</a></p>
|
||||||
|
{machine_body_line}
|
||||||
<p style="margin: 0;"><strong>Reason:</strong> {safe_reason}</p>
|
<p style="margin: 0;"><strong>Reason:</strong> {safe_reason}</p>
|
||||||
<p style="margin: 0;"><strong>Reported:</strong> {escape(reported_at)}</p>
|
<p style="margin: 0;"><strong>Reported:</strong> {escape(reported_at)}</p>
|
||||||
</div>
|
</div>
|
||||||
@@ -3008,7 +3044,7 @@ def _send_operator_report_alert(report, asset_id, hostname):
|
|||||||
</div>
|
</div>
|
||||||
'''
|
'''
|
||||||
|
|
||||||
subject = f'Operator Issue Report: {safe_name} ({safe_assetnumber})'
|
subject = f'Operator Issue Report: {safe_hostname}{machine_subject_part}'
|
||||||
|
|
||||||
current_app.logger.info('Sending operator report alert for %s (report %d)',
|
current_app.logger.info('Sending operator report alert for %s (report %d)',
|
||||||
hostname, report.operatorreportid)
|
hostname, report.operatorreportid)
|
||||||
|
|||||||
Reference in New Issue
Block a user