Sidhra_Audit_System/sidrah_business/patches/rebuild_workflow_notifications.py
2026-10-09 12:16:48 +05:30

155 lines
7.8 KiB
Python

import frappe
# Supersedes create_resolution_notifications.py and create_workflow_step_notifications.py:
# same idea, but event='Value Change' + a `doc.workflow_state == "..."` condition per
# state (matching the "Idea Is in Accept & Under Progress" example), one record per
# *state* rather than per action — several actions land on the same state (e.g. Process's
# "Submit for Review" and "Start New Cycle" both end in Pending Actor), so this is also
# fewer records than the per-action version. sidrah_business.api._fire_alert() still
# calls `.send(doc)` explicitly right after workflow_state is set (event='Value Change'
# alone won't auto-fire here — workflow_state moves via frappe.db.set_value to dodge
# Frappe's own Workflow permission check, so Frappe's own auto-dispatch never sees it
# change) — the condition on each record is honored by _fire_alert before it sends, so
# editing a condition in Desk still changes real behavior.
_SENDER_ACCOUNT = 'Asset Notifications'
_OLD_NAMES = [
'SB Incident Resolved', 'SB Idea Resolved', 'SB Order Closed',
'SB Process - Submit for Review', 'SB Process - Update Status',
'SB Process - Add Comment', 'SB Process - Move to Study', 'SB Process - Start New Cycle',
'SB Order - Submit for Review', 'SB Order - Update Status',
'SB Order - Move to Study', 'SB Order - Start New Cycle',
'SB Incident - Submit', 'SB Incident - Assign to Manager', 'SB Incident - Reject',
'SB Idea - Submit', 'SB Idea - Assign to Manager', 'SB Idea - Reject', 'SB Idea - Submit Proposal',
]
_ALERTS = [
# ── SB Idea ──────────────────────────────────────────────────────────────
{
'name': 'SB Idea - Initial Evaluation', 'document_type': 'SB Idea', 'state': 'Initial Evaluation',
'subject': '{{ doc.name }} Idea Is in Initial Evaluation. Take Necessary Action',
'recipients': [{'receiver_by_role': 'SB Auditor'}],
},
{
'name': 'SB Idea - Accept & Under Progress', 'document_type': 'SB Idea', 'state': 'Accept & Under Progress',
'subject': '{{ doc.name }} Idea Is in Accept & Under Progress. Take Necessary Action',
'recipients': [{'receiver_by_document_field': 'assigned_to'}],
},
{
'name': 'SB Idea - working on proposal', 'document_type': 'SB Idea', 'state': 'working on proposal',
'subject': '{{ doc.name }} Idea Is in working on proposal. Take Necessary Action',
'recipients': [{'receiver_by_role': 'SB Auditor'}],
},
{
'name': 'SB Idea - Executed & Closed', 'document_type': 'SB Idea', 'state': 'Executed & Closed',
'subject': '{{ doc.name }} Idea Is in Executed & Closed. Take Necessary Action',
'recipients': [{'receiver_by_document_field': 'owner'}],
},
{
'name': 'SB Idea - Rejected', 'document_type': 'SB Idea', 'state': 'Rejected',
'subject': '{{ doc.name }} Idea Is in Rejected. Take Necessary Action',
'recipients': [{'receiver_by_document_field': 'owner'}],
},
# ── SB Incident ──────────────────────────────────────────────────────────
{
'name': 'SB Incident - Initial Evaluation', 'document_type': 'SB Incident', 'state': 'Initial Evaluation',
'subject': '{{ doc.name }} Incident Is in Initial Evaluation. Take Necessary Action',
'recipients': [{'receiver_by_role': 'SB Auditor'}],
},
{
'name': 'SB Incident - Accept & Under Progress', 'document_type': 'SB Incident', 'state': 'Accept & Under Progress',
'subject': '{{ doc.name }} Incident Is in Accept & Under Progress. Take Necessary Action',
'recipients': [{'receiver_by_document_field': 'assigned_to'}],
},
{
'name': 'SB Incident - Executed & Closed', 'document_type': 'SB Incident', 'state': 'Executed & Closed',
'subject': '{{ doc.name }} Incident Is in Executed & Closed. Take Necessary Action',
'recipients': [{'receiver_by_document_field': 'owner'}],
},
{
'name': 'SB Incident - Rejected', 'document_type': 'SB Incident', 'state': 'Rejected',
'subject': '{{ doc.name }} Incident Is in Rejected. Take Necessary Action',
'recipients': [{'receiver_by_document_field': 'owner'}],
},
# ── SB Process ───────────────────────────────────────────────────────────
{
'name': 'SB Process - Pending Actor', 'document_type': 'SB Process', 'state': 'Pending Actor',
'subject': '{{ doc.name }} Process Is in Pending Actor. Take Necessary Action',
'recipients': [{'receiver_by_document_field': 'actor'}],
},
{
'name': 'SB Process - Pending Comment', 'document_type': 'SB Process', 'state': 'Pending Comment',
'subject': '{{ doc.name }} Process Is in Pending Comment. Take Necessary Action',
'recipients': [{'receiver_by_role': 'SB Auditor'}, {'receiver_by_role': 'SB Manager'}],
},
{
'name': 'SB Process - Review', 'document_type': 'SB Process', 'state': 'Review',
'subject': '{{ doc.name }} Process Is in Review. Take Necessary Action',
'recipients': [{'receiver_by_role': 'SB Auditor'}, {'receiver_by_role': 'SB Manager'}],
},
{
'name': 'SB Process - In Study', 'document_type': 'SB Process', 'state': 'In Study',
'subject': '{{ doc.name }} Process Is in In Study. Take Necessary Action',
'recipients': [{'receiver_by_role': 'SB Auditor'}, {'receiver_by_role': 'SB Manager'}],
},
# ── SB Order ─────────────────────────────────────────────────────────────
{
'name': 'SB Order - Pending Actor', 'document_type': 'SB Order', 'state': 'Pending Actor',
'subject': '{{ doc.name }} Order Is in Pending Actor. Take Necessary Action',
'recipients': [{'receiver_by_document_field': 'actor'}],
},
{
'name': 'SB Order - Review', 'document_type': 'SB Order', 'state': 'Review',
'subject': '{{ doc.name }} Order Is in Review. Take Necessary Action',
'recipients': [{'receiver_by_role': 'SB Auditor'}, {'receiver_by_role': 'SB Manager'}, {'receiver_by_role': 'SB Owner'}],
},
{
'name': 'SB Order - In Study', 'document_type': 'SB Order', 'state': 'In Study',
'subject': '{{ doc.name }} Order Is in In Study. Take Necessary Action',
'recipients': [{'receiver_by_role': 'SB Auditor'}, {'receiver_by_role': 'SB Manager'}, {'receiver_by_role': 'SB Owner'}],
},
{
'name': 'SB Order - Closed', 'document_type': 'SB Order', 'state': 'Closed',
'subject': '{{ doc.name }} Order Is in Closed. Take Necessary Action',
'recipients': [{'receiver_by_document_field': 'owner'}],
},
]
def execute():
for old_name in _OLD_NAMES:
if frappe.db.exists('Notification', old_name):
frappe.delete_doc('Notification', old_name, ignore_permissions=True, force=True)
if not frappe.db.exists('Email Account', _SENDER_ACCOUNT):
frappe.db.commit()
return
for spec in _ALERTS:
if frappe.db.exists('Notification', spec['name']):
frappe.delete_doc('Notification', spec['name'], ignore_permissions=True, force=True)
frappe.get_doc({
'doctype': 'Notification',
'name': spec['name'],
'subject': spec['subject'],
'document_type': spec['document_type'],
'event': 'Value Change',
'value_changed': 'workflow_state',
'condition': 'doc.workflow_state == "{}"'.format(spec['state']),
'channel': 'Email',
'sender': _SENDER_ACCOUNT,
# In-app bell notifications for the same step are already sent precisely
# (organization-scoped) by sidrah_business.api._send_notification — leaving
# this off avoids a second, broader-audience bell entry for the same event.
'send_system_notification': 0,
'message_type': 'Markdown',
'message': '<p>{{ doc.title or doc.name }} — {}</p>'.format(spec['state']),
'attach_print': 0,
'recipients': spec['recipients'],
}).insert(ignore_permissions=True)
frappe.db.commit()