Aug 17 - Update customer roles management
This commit is contained in:
@@ -337,6 +337,7 @@ def notify_customers_for_facility(
|
||||
link: str = None,
|
||||
issue_id: int = None,
|
||||
inspection_id: int = None,
|
||||
allowed_user_ids: set = None,
|
||||
):
|
||||
"""Dispatch in-app + email notifications to all customer users assigned
|
||||
to the given facility.
|
||||
@@ -357,6 +358,12 @@ def notify_customers_for_facility(
|
||||
link : Relative URL for 'View Details'.
|
||||
issue_id : FK to issues.id (optional).
|
||||
inspection_id : FK to inspections.id (optional).
|
||||
allowed_user_ids :
|
||||
Optional whitelist. When notify_by_matrix() calls this it has already
|
||||
applied each account's per-event override (phase51), so it passes the
|
||||
surviving ids here — this function re-derives recipients from the
|
||||
assignment rows and would otherwise notify accounts that opted out.
|
||||
None (the default, used by direct callers) means no filtering.
|
||||
"""
|
||||
try:
|
||||
from app.models.project import CustomerAssignment
|
||||
@@ -394,8 +401,20 @@ def notify_customers_for_facility(
|
||||
)
|
||||
return
|
||||
|
||||
if allowed_user_ids is not None:
|
||||
notified_user_ids &= set(allowed_user_ids)
|
||||
if not notified_user_ids:
|
||||
logger.debug(
|
||||
'notify_customers_for_facility | facility_id=%s | all '
|
||||
'assigned customers filtered out by per-account overrides',
|
||||
facility_id,
|
||||
)
|
||||
return
|
||||
|
||||
for user_id in notified_user_ids:
|
||||
user = db.session.get(User, user_id)
|
||||
# role != 'customer' stays an EQUALITY check: a Customer Inspector
|
||||
# is not a portal customer and is routed by the inspector column.
|
||||
if not user or not user.active or user.role != 'customer':
|
||||
continue
|
||||
try:
|
||||
@@ -557,11 +576,20 @@ def notify_by_matrix(
|
||||
from app.models.notification_matrix import (
|
||||
is_enabled, get_custom_emails_for, MATRIX_ROLES,
|
||||
)
|
||||
from app.models.user_notification_matrix import overrides_for_event
|
||||
from app.models.user import User
|
||||
|
||||
exclude = set(exclude_user_ids or [])
|
||||
notified = set() # deduplicate across roles
|
||||
|
||||
# ── Per-account overrides (phase51) ───────────────────────────────────
|
||||
# {user_id: bool} for this event, one query. Applies to the two
|
||||
# customer-side role columns only; staff roles use the global matrix alone.
|
||||
# An account with no entry inherits the global column, which is why this
|
||||
# feature is a no-op until an admin actually sets something.
|
||||
overrides = overrides_for_event(event_type)
|
||||
customer_keys = User.CUSTOMER_ROLES # ('customer', 'external_inspector')
|
||||
|
||||
role_to_db = {
|
||||
'admin': 'admin',
|
||||
'director': 'director',
|
||||
@@ -580,7 +608,14 @@ def notify_by_matrix(
|
||||
enabled = is_enabled(event_type, role_key)
|
||||
logger.info('MATRIX NOTIFY | event=%s | role=%s | enabled=%s',
|
||||
event_type, role_key, enabled)
|
||||
if not enabled:
|
||||
|
||||
# A customer-side column must NOT be skipped just because the global
|
||||
# switch is off — an account that opted IN individually still has to be
|
||||
# reached. Only skip when the column is off AND nobody opted in.
|
||||
# (Getting this wrong is silent: the per-account "on" would save fine,
|
||||
# show as on, and never send.)
|
||||
is_customer_col = role_key in customer_keys
|
||||
if not enabled and not (is_customer_col and any(overrides.values())):
|
||||
continue
|
||||
|
||||
db_role = role_to_db.get(role_key)
|
||||
@@ -607,6 +642,15 @@ def notify_by_matrix(
|
||||
'submitting inspector_id=%s',
|
||||
event_type, role_key, target_id)
|
||||
|
||||
# Apply the per-account overrides to the customer-side columns. An
|
||||
# account with no override falls back to `enabled`, i.e. the global
|
||||
# column — so this line is what makes both directions work: opt-in
|
||||
# against an off column, and opt-out of an on one.
|
||||
if is_customer_col:
|
||||
users = [u for u in users if overrides.get(u.id, enabled)]
|
||||
logger.info('MATRIX NOTIFY | event=%s | role=%s | after overrides=%s',
|
||||
event_type, role_key, [u.username for u in users])
|
||||
|
||||
# Scope customer role to facility if provided
|
||||
if role_key == 'customer' and facility_id:
|
||||
from app.utils.notifications import notify_customers_for_facility
|
||||
@@ -618,6 +662,9 @@ def notify_by_matrix(
|
||||
link = link,
|
||||
issue_id = issue_id,
|
||||
inspection_id = inspection_id,
|
||||
# Without this the facility-scoped path would re-query customers
|
||||
# itself and bypass every override applied just above.
|
||||
allowed_user_ids = {u.id for u in users},
|
||||
)
|
||||
continue # notify_customers_for_facility handles dedup internally
|
||||
|
||||
|
||||
Reference in New Issue
Block a user