From 974763d66eb1b6db61d2f8a69d42e8c2d5151e0a Mon Sep 17 00:00:00 2001 From: muhammad-ammar Date: Thu, 18 Aug 2022 19:08:56 +0500 Subject: [PATCH] feat: Update LearnerCourseEvent model and management command to track sent events. * Add `already_sent` boolean field in `LearnerCourseEvent` model to store the state for sent events. * Set `already_sent`` to `True` in `LearnerCourseEvent` model for each triggered event. --- CHANGELOG.rst | 5 ++++ outcome_surveys/__init__.py | 2 +- ...w_up_segment_events_for_passed_learners.py | 6 +++++ ...w_up_segment_events_for_passed_learners.py | 27 ++++++++++++++++++- .../0002_learnercourseevent_already_sent.py | 18 +++++++++++++ outcome_surveys/models.py | 1 + 6 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 outcome_surveys/migrations/0002_learnercourseevent_already_sent.py diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 8c21bb5..dfb7a44 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -15,6 +15,11 @@ Unreleased ~~~~~~~~~~ +[1.1.1] - 2022-09-06 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +* Add `already_sent` boolean field in `LearnerCourseEvent` model to store the state for sent events. +* Set `already_sent`` to `True` in `LearnerCourseEvent` model for each triggered event. + [1.1.0] - 2022-07-14 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Make follow up days configurable diff --git a/outcome_surveys/__init__.py b/outcome_surveys/__init__.py index 35832e1..7dccee9 100644 --- a/outcome_surveys/__init__.py +++ b/outcome_surveys/__init__.py @@ -2,6 +2,6 @@ Outcome Surveys. """ -__version__ = '1.1.0' +__version__ = '1.1.1' default_app_config = 'outcome_surveys.apps.OutcomeSurveysConfig' # pylint: disable=invalid-name diff --git a/outcome_surveys/management/commands/send_follow_up_segment_events_for_passed_learners.py b/outcome_surveys/management/commands/send_follow_up_segment_events_for_passed_learners.py index 6e715d8..ea86959 100644 --- a/outcome_surveys/management/commands/send_follow_up_segment_events_for_passed_learners.py +++ b/outcome_surveys/management/commands/send_follow_up_segment_events_for_passed_learners.py @@ -59,12 +59,14 @@ def handle(self, *args, **options): follow_up_events = LearnerCourseEvent.objects.filter( follow_up_date=today, event_type=SEGMENT_LEARNER_PASSED_COURSE_FIRST_TIME_EVENT_TYPE, + already_sent=False, ) paginator = Paginator(follow_up_events, 500) for page_number in paginator.page_range: page = paginator.page(page_number) + triggered_event_record_ids = [] for follow_up_event in page: if should_fire_event: track( @@ -72,6 +74,7 @@ def handle(self, *args, **options): SEGMENT_LEARNER_PASSED_COURSE_FIRST_TIME_FOLLOW_UP_EVENT_TYPE, follow_up_event.data ) + triggered_event_record_ids.append(follow_up_event.id) follow_up_event_ids.append(follow_up_event.id) @@ -82,4 +85,7 @@ def handle(self, *args, **options): follow_up_event.data ) + if triggered_event_record_ids: + LearnerCourseEvent.objects.filter(id__in=triggered_event_record_ids).update(already_sent=True) + log.info("%s Command completed. Segment event triggered for ids: [%s]", log_prefix, follow_up_event_ids) diff --git a/outcome_surveys/management/commands/tests/test_send_follow_up_segment_events_for_passed_learners.py b/outcome_surveys/management/commands/tests/test_send_follow_up_segment_events_for_passed_learners.py index d96f1e8..151e666 100644 --- a/outcome_surveys/management/commands/tests/test_send_follow_up_segment_events_for_passed_learners.py +++ b/outcome_surveys/management/commands/tests/test_send_follow_up_segment_events_for_passed_learners.py @@ -54,6 +54,18 @@ def setUp(self): 'follow_up_date': self.today, 'event_type': SEGMENT_LEARNER_PASSED_COURSE_FIRST_TIME_EVENT_TYPE, }, + { + 'user_id': 222, + 'course_id': self.course_id, + 'data': { + 'LMS_ENROLLMENT_ID': 2221, + 'COURSE_TITLE': 'An introduction to Python', + 'COURSE_ORG_NAME': 'PythonX', + }, + 'follow_up_date': self.today, + 'event_type': SEGMENT_LEARNER_PASSED_COURSE_FIRST_TIME_EVENT_TYPE, + 'already_sent': True, + }, { 'user_id': 300, 'course_id': self.course_id, @@ -76,7 +88,7 @@ def construct_event_call_data(self): """ event_call_data = [] for item in self.test_data: - if item.get('follow_up_date') == self.today: + if item.get('follow_up_date') == self.today and item.get('already_sent', False) is False: event_call_data.append([ item.get('user_id'), SEGMENT_LEARNER_PASSED_COURSE_FIRST_TIME_FOLLOW_UP_EVENT_TYPE, @@ -99,6 +111,19 @@ def test_command(self, segment_track_mock): * Event should be fired for records having follow_up_date set to today. """ + already_sent_records = LearnerCourseEvent.objects.filter(already_sent=True) + assert already_sent_records.count() == 1 + assert already_sent_records.first().user_id == 222 + already_sent_records_ids = list(already_sent_records.values_list('id', flat=True)) + call_command(self.command) expected_segment_event_calls = [mock.call(*event_data) for event_data in self.construct_event_call_data()] segment_track_mock.assert_has_calls(expected_segment_event_calls) + + # verify that correct records were upddated in table + already_sent_records = LearnerCourseEvent.objects.filter(already_sent=True) + assert already_sent_records.count() == 3 + triggered_event_user_ids = already_sent_records.exclude( + id__in=already_sent_records_ids + ).values_list('user_id', flat=True) + assert list(triggered_event_user_ids) == [100, 200] diff --git a/outcome_surveys/migrations/0002_learnercourseevent_already_sent.py b/outcome_surveys/migrations/0002_learnercourseevent_already_sent.py new file mode 100644 index 0000000..13aa652 --- /dev/null +++ b/outcome_surveys/migrations/0002_learnercourseevent_already_sent.py @@ -0,0 +1,18 @@ +# Generated by Django 3.2.14 on 2022-08-18 09:08 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('outcome_surveys', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='learnercourseevent', + name='already_sent', + field=models.BooleanField(default=False), + ), + ] diff --git a/outcome_surveys/models.py b/outcome_surveys/models.py index 0f191a1..70fa134 100644 --- a/outcome_surveys/models.py +++ b/outcome_surveys/models.py @@ -30,6 +30,7 @@ class LearnerCourseEvent(TimeStampedModel): choices=EVENT_CHOICES, default=SEGMENT_LEARNER_PASSED_COURSE_FIRST_TIME_EVENT_TYPE, ) + already_sent = models.BooleanField(default=False) class Meta: """