From de230d6da1c2579039a16ed9869bdfbb5b2dc852 Mon Sep 17 00:00:00 2001 From: Alejandro Sanchez Date: Mon, 9 Oct 2023 17:08:00 -0400 Subject: [PATCH 1/7] Update serializers.py --- breathecode/events/serializers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/breathecode/events/serializers.py b/breathecode/events/serializers.py index 19580f4f5..f883d6621 100644 --- a/breathecode/events/serializers.py +++ b/breathecode/events/serializers.py @@ -614,7 +614,7 @@ def validate(self, data): def create(self, validated_data): event_checkin = super().create(validated_data) - tasks_activity.add_activity.delay(event_checkin.attendee, + tasks_activity.add_activity.delay(event_checkin.attendee.id, 'event_checkin_created', related_type='events.EventCheckin', related_id=event_checkin.id) From a36c92b694c9e08392ebd3863bde4e3c9894c075 Mon Sep 17 00:00:00 2001 From: Alejandro Sanchez Date: Mon, 9 Oct 2023 22:39:35 +0000 Subject: [PATCH 2/7] now saving utm information from incoming events --- breathecode/assignments/serializers.py | 3 ++- breathecode/events/models.py | 5 +++++ .../tests/urls/tests_eventbrite_webhook_id.py | 20 +++++++++++++++++++ .../tests/urls/tests_me_event_id_join.py | 4 ++++ .../eventbrite/actions/order_placed.py | 1 + 5 files changed, 32 insertions(+), 1 deletion(-) diff --git a/breathecode/assignments/serializers.py b/breathecode/assignments/serializers.py index 7671a51cc..f3b592a16 100644 --- a/breathecode/assignments/serializers.py +++ b/breathecode/assignments/serializers.py @@ -215,7 +215,8 @@ def validate(self, data): return data def update(self, instance, validated_data): - if 'opened_at' in validated_data and validated_data['opened_at'] > instance.opened_at: + if 'opened_at' in validated_data and (instance.opened_at is None + or validated_data['opened_at'] > instance.opened_at): tasks_activity.add_activity.delay(self.context['request'].user.id, 'read_assignment', related_type='assignments.Task', diff --git a/breathecode/events/models.py b/breathecode/events/models.py index ab135c703..4e5ab8d51 100644 --- a/breathecode/events/models.py +++ b/breathecode/events/models.py @@ -300,6 +300,11 @@ def __init__(self, *args, **kwargs): event = models.ForeignKey(Event, on_delete=models.CASCADE) status = models.CharField(max_length=9, choices=CHECKIN_STATUS, default=PENDING) + utm_medium = models.CharField(max_length=70, blank=True, null=True, default=None) + utm_campaign = models.CharField(max_length=70, blank=True, null=True, default=None) + utm_source = models.CharField(max_length=70, blank=True, null=True, default=None) + utm_url = models.CharField(max_length=2000, null=True, default=None, blank=True) + created_at = models.DateTimeField(auto_now_add=True, editable=False) updated_at = models.DateTimeField(auto_now=True, editable=False) attended_at = models.DateTimeField(null=True, default=None, blank=True) diff --git a/breathecode/events/tests/urls/tests_eventbrite_webhook_id.py b/breathecode/events/tests/urls/tests_eventbrite_webhook_id.py index c373bebcb..b34a52074 100644 --- a/breathecode/events/tests/urls/tests_eventbrite_webhook_id.py +++ b/breathecode/events/tests/urls/tests_eventbrite_webhook_id.py @@ -219,6 +219,10 @@ def test_eventbrite_webhook_without_active_campaign_academy(self): 'email': 'john.smith@example.com', 'event_id': 1, 'id': 1, + 'utm_campaign': None, + 'utm_medium': None, + 'utm_source': None, + 'utm_url': None, 'status': 'PENDING', 'attended_at': None }]) @@ -263,6 +267,10 @@ def test_eventbrite_webhook_without_automation(self): self.assertEqual(self.all_event_checkin_dict(), [{ 'attendee_id': None, 'email': 'john.smith@example.com', + 'utm_campaign': None, + 'utm_medium': None, + 'utm_source': None, + 'utm_url': None, 'event_id': 1, 'id': 1, 'status': 'PENDING', @@ -321,6 +329,10 @@ def test_eventbrite_webhook_without_lang(self): self.assertEqual(self.all_event_checkin_dict(), [{ 'attendee_id': 1, + 'utm_campaign': None, + 'utm_medium': None, + 'utm_source': None, + 'utm_url': None, 'email': 'john.smith@example.com', 'event_id': 1, 'id': 1, @@ -417,6 +429,10 @@ def test_eventbrite_webhook_without_lang__active_campaign_belong_to_other_academ self.assertEqual(self.all_event_checkin_dict(), [{ 'attendee_id': 1, + 'utm_campaign': None, + 'utm_medium': None, + 'utm_source': None, + 'utm_url': None, 'email': 'john.smith@example.com', 'event_id': 1, 'id': 1, @@ -514,6 +530,10 @@ def test_eventbrite_webhook(self): self.assertEqual(self.all_event_checkin_dict(), [{ 'attendee_id': 1, + 'utm_campaign': None, + 'utm_medium': None, + 'utm_source': None, + 'utm_url': None, 'email': 'john.smith@example.com', 'event_id': 1, 'id': 1, diff --git a/breathecode/events/tests/urls/tests_me_event_id_join.py b/breathecode/events/tests/urls/tests_me_event_id_join.py index 97d2b4422..f77c48e06 100644 --- a/breathecode/events/tests/urls/tests_me_event_id_join.py +++ b/breathecode/events/tests/urls/tests_me_event_id_join.py @@ -45,6 +45,10 @@ def event_checkin_serializer(id, event, user): return { 'attended_at': UTC_NOW, 'attendee_id': user.id, + 'utm_campaign': None, + 'utm_medium': None, + 'utm_source': None, + 'utm_url': None, 'email': user.email, 'event_id': event.id, 'id': id, diff --git a/breathecode/services/eventbrite/actions/order_placed.py b/breathecode/services/eventbrite/actions/order_placed.py index fed9fa2b2..2a7fd21c5 100644 --- a/breathecode/services/eventbrite/actions/order_placed.py +++ b/breathecode/services/eventbrite/actions/order_placed.py @@ -50,6 +50,7 @@ def order_placed(self, webhook, payload: dict): elif not EventCheckin.objects.filter(email=email, event=local_event, attendee=local_attendee).count(): event_checkin = EventCheckin.objects.filter(email=email, event=local_event).first() event_checkin.attendee = local_attendee + event_checkin.utm_source = 'eventbrite' event_checkin.save() contact = { From 90754f090a6766fe4d9c040ac957539dc13340d9 Mon Sep 17 00:00:00 2001 From: Alejandro Sanchez Date: Mon, 9 Oct 2023 22:41:49 +0000 Subject: [PATCH 3/7] now saving utm information from incoming events --- .../migrations/0055_auto_20231009_2240.py | 33 +++++++++++++++++++ breathecode/events/serializers.py | 4 +++ 2 files changed, 37 insertions(+) create mode 100644 breathecode/events/migrations/0055_auto_20231009_2240.py diff --git a/breathecode/events/migrations/0055_auto_20231009_2240.py b/breathecode/events/migrations/0055_auto_20231009_2240.py new file mode 100644 index 000000000..1b50ae008 --- /dev/null +++ b/breathecode/events/migrations/0055_auto_20231009_2240.py @@ -0,0 +1,33 @@ +# Generated by Django 3.2.21 on 2023-10-09 22:40 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('events', '0054_alter_event_uuid'), + ] + + operations = [ + migrations.AddField( + model_name='eventcheckin', + name='utm_campaign', + field=models.CharField(blank=True, default=None, max_length=70, null=True), + ), + migrations.AddField( + model_name='eventcheckin', + name='utm_medium', + field=models.CharField(blank=True, default=None, max_length=70, null=True), + ), + migrations.AddField( + model_name='eventcheckin', + name='utm_source', + field=models.CharField(blank=True, default=None, max_length=70, null=True), + ), + migrations.AddField( + model_name='eventcheckin', + name='utm_url', + field=models.CharField(blank=True, default=None, max_length=2000, null=True), + ), + ] diff --git a/breathecode/events/serializers.py b/breathecode/events/serializers.py index f883d6621..c152b5ab0 100644 --- a/breathecode/events/serializers.py +++ b/breathecode/events/serializers.py @@ -416,6 +416,10 @@ class EventHookCheckinSerializer(serpy.Serializer): id = serpy.Field() email = serpy.Field() status = serpy.Field() + utm_url = serpy.Field() + utm_source = serpy.Field() + utm_campaign = serpy.Field() + utm_medium = serpy.Field() created_at = serpy.Field() attended_at = serpy.Field() attendee = UserSerializer(required=False) From b5b5fc1e929480217c36df2b4cb92f2f2581d364 Mon Sep 17 00:00:00 2001 From: Alejandro Sanchez Date: Mon, 9 Oct 2023 19:11:35 -0400 Subject: [PATCH 4/7] Update admin.py --- breathecode/events/admin.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/breathecode/events/admin.py b/breathecode/events/admin.py index 2bd3e0c6e..e150e6efc 100644 --- a/breathecode/events/admin.py +++ b/breathecode/events/admin.py @@ -104,8 +104,8 @@ class EventTypeAdmin(admin.ModelAdmin): # Register your models here. @admin.register(EventCheckin) class EventCheckinAdmin(admin.ModelAdmin): - list_display = ('id', 'email', 'attendee', 'event', 'status', 'created_at', 'attended_at') - list_filter = ['status'] + list_display = ('id', 'email', 'attendee', 'event', 'status', 'created_at', 'attended_at', 'utm_source') + list_filter = ['status', 'utm_source', 'utm_medium'] search_fields = ['email', 'event__title', 'event__slug'] raw_id_fields = ['event', 'attendee'] From e62973ea32d1292cd32c187f5c26e718bb34006b Mon Sep 17 00:00:00 2001 From: Alejandro Sanchez Date: Tue, 10 Oct 2023 09:57:37 -0400 Subject: [PATCH 5/7] Update views.py --- breathecode/assignments/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/breathecode/assignments/views.py b/breathecode/assignments/views.py index 741632cc8..64e4dfdf8 100644 --- a/breathecode/assignments/views.py +++ b/breathecode/assignments/views.py @@ -644,7 +644,7 @@ def post(self, request, user_id=None): tasks_activity.add_activity.delay(request.user.id, 'open_syllabus_module', related_type='assignments.Task', - related_id=serializer.id) + related_id=serializer.data['id']) return Response(serializer.data, status=status.HTTP_201_CREATED) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) From 5dac22060e8aeeab7a03ae470244da4305ba5432 Mon Sep 17 00:00:00 2001 From: Alejandro Sanchez Date: Tue, 10 Oct 2023 10:53:47 -0400 Subject: [PATCH 6/7] Update views.py --- breathecode/assignments/views.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/breathecode/assignments/views.py b/breathecode/assignments/views.py index 64e4dfdf8..5c8e6a448 100644 --- a/breathecode/assignments/views.py +++ b/breathecode/assignments/views.py @@ -639,12 +639,12 @@ def post(self, request, user_id=None): }, many=True) if serializer.is_valid(): - serializer.save() + task = serializer.save() # tasks.teacher_task_notification.delay(serializer.data['id']) tasks_activity.add_activity.delay(request.user.id, 'open_syllabus_module', related_type='assignments.Task', - related_id=serializer.data['id']) + related_id=task.id) return Response(serializer.data, status=status.HTTP_201_CREATED) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) From c0645024955b493560e07ce273e23cc55204cd2d Mon Sep 17 00:00:00 2001 From: Alejandro Sanchez Date: Tue, 10 Oct 2023 11:20:44 -0400 Subject: [PATCH 7/7] Update views.py --- breathecode/assignments/views.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/breathecode/assignments/views.py b/breathecode/assignments/views.py index 5c8e6a448..542c7801f 100644 --- a/breathecode/assignments/views.py +++ b/breathecode/assignments/views.py @@ -639,12 +639,14 @@ def post(self, request, user_id=None): }, many=True) if serializer.is_valid(): - task = serializer.save() + tasks = serializer.save() # tasks.teacher_task_notification.delay(serializer.data['id']) - tasks_activity.add_activity.delay(request.user.id, - 'open_syllabus_module', - related_type='assignments.Task', - related_id=task.id) + for t in tasks: + tasks_activity.add_activity.delay(request.user.id, + 'open_syllabus_module', + related_type='assignments.Task', + related_id=t.id) + return Response(serializer.data, status=status.HTTP_201_CREATED) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)