Skip to content

Commit 78d2b3c

Browse files
authored
Merge pull request #2747 from IFRCGo/feat/add-default-daily-alert-limit
Alert-syetem: Add default daily email alert limit
2 parents 1571c96 + af8546a commit 78d2b3c

3 files changed

Lines changed: 45 additions & 19 deletions

File tree

alert_system/email_processing.py

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414

1515
logger = logging.getLogger(__name__)
1616

17+
DEFAULT_ALERT_PER_DAY = 100
18+
1719

1820
def send_alert_email_notification(
1921
load_item: LoadItem,
@@ -56,26 +58,33 @@ def send_alert_email_notification(
5658
html=email_body,
5759
mailtype=email_type,
5860
)
59-
61+
# Create thread for initial emails
6062
email_log.status = AlertEmailLog.Status.SENT
6163
email_log.email_sent_at = timezone.now()
62-
email_log.save(update_fields=["status", "email_sent_at"])
6364

64-
# Create thread for initial emails
6565
if not is_reply:
66-
thread = AlertEmailThread.objects.create(
66+
thread, created = AlertEmailThread.objects.get_or_create(
6767
user=user,
6868
parent_event_id=load_item.parent_event_id,
69-
root_email_message_id=message_id,
70-
root_message_sent_at=timezone.now(),
69+
defaults={
70+
"root_email_message_id": message_id,
71+
"root_message_sent_at": timezone.now(),
72+
},
7173
)
7274
email_log.thread = thread
73-
email_log.save(update_fields=["thread"])
74-
logger.info(
75-
f"Alert Email thread created for user [{user.get_full_name()}] "
76-
f"with parent event [{load_item.parent_event_id}]"
77-
)
78-
75+
email_log.save(update_fields=["status", "email_sent_at", "thread"])
76+
77+
if created:
78+
logger.info(
79+
f"Alert Email thread created for user [{user.get_full_name()}] "
80+
f"with parent event [{load_item.parent_event_id}]"
81+
)
82+
else:
83+
logger.info(
84+
f"Existing thread found for user [{user.get_full_name()}] " f"with parent event [{load_item.parent_event_id}]"
85+
)
86+
else:
87+
email_log.save(update_fields=["status", "email_sent_at"])
7988
logger.info(f"Alert email sent to [{user.get_full_name()}] for LoadItem ID [{load_item.id}]")
8089

8190
except Exception:
@@ -141,15 +150,16 @@ def process_email_alert(load_item_id: int) -> None:
141150
thread = existing_threads.get(user_id)
142151
is_reply: bool = thread is not None
143152

153+
# Skip duplicate emails for same item
154+
if (user_id, subscription_id) in already_sent:
155+
logger.info(f"Duplicate alert skipped for user [{user.get_full_name()}] " f"with LoadItem ID [{load_item_id}]")
156+
continue
157+
144158
# Skip if daily alert limit reached
145159
sent_today: int = daily_count_map.get((user_id, subscription_id), 0)
146-
if subscription.alert_per_day and sent_today >= subscription.alert_per_day:
160+
effective_limit = subscription.alert_per_day or DEFAULT_ALERT_PER_DAY
161+
if sent_today >= effective_limit:
147162
logger.info(f"Daily alert limit reached for user [{user.get_full_name()}]")
148163
continue
149164

150-
# Skip duplicate emails for same item
151-
if (user_id, subscription_id) in already_sent:
152-
logger.info(f"Duplicate alert skipped for user [{user.get_full_name()}] " f"with LoadItem ID [{subscription_id}]")
153-
continue
154-
155165
send_alert_email_notification(load_item=load_item, user=user, subscription=subscription, thread=thread, is_reply=is_reply)
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Generated by Django 4.2.30 on 2026-05-26 04:11
2+
3+
from django.db import migrations
4+
5+
6+
class Migration(migrations.Migration):
7+
8+
dependencies = [
9+
('alert_system', '0002_remove_alertemailthread_unique_user_guid_and_more'),
10+
]
11+
12+
operations = [
13+
migrations.RemoveConstraint(
14+
model_name='alertemailthread',
15+
name='unique_user_parent_event',
16+
),
17+
]

alert_system/models.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,6 @@ class Meta:
304304
verbose_name = _("Email Thread")
305305
verbose_name_plural = _("Email Threads")
306306
ordering = ["-id"]
307-
constraints = [models.UniqueConstraint(fields=["parent_event_id", "user"], name="unique_user_parent_event")]
308307
indexes = [
309308
models.Index(fields=["parent_event_id", "user"]),
310309
]

0 commit comments

Comments
 (0)