-
-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathunsubscribe_command.py
More file actions
68 lines (61 loc) · 2.29 KB
/
Copy pathunsubscribe_command.py
File metadata and controls
68 lines (61 loc) · 2.29 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
from typing import Literal
from django_email_learning.models import (
Course,
Enrollment,
DeliveryStatus,
Learner,
EnrollmentStatus,
DeactivationReason,
)
from django.utils import timezone
from django_email_learning.services.command_models.abstract_command import (
AbstractCommand,
)
from django_email_learning.services.command_models.exceptions.invalid_course_slug_error import (
InvalidCourseSlugError,
)
class UnsubscribeCommand(AbstractCommand):
command_name: Literal["unsubscribe"] = "unsubscribe"
email: str
course_slug: str
organization_id: int
def execute(self) -> None:
try:
course = Course.objects.get(
slug=self.course_slug, organization_id=self.organization_id
)
except Course.DoesNotExist:
self.logger.error(
f"Unsubscribe Failed: Invalid course slug '{self.course_slug}' for organization ID {self.organization_id}"
)
raise InvalidCourseSlugError(
f"Course with slug '{self.course_slug}' does not exist for organization ID {self.organization_id}"
)
try:
learner = Learner.objects.get(
email=self.email,
organization_id=self.organization_id, # type: ignore[misc]
)
except Learner.DoesNotExist:
self.logger.warning(
f"Unsubscribe Skipped: No learner found with email {self.email}"
)
return
enrollments = Enrollment.objects.filter(learner=learner, course=course).exclude(
status=EnrollmentStatus.DEACTIVATED
)
if not enrollments.exists():
self.logger.warning(
f"Unsubscribe Skipped: No active enrollment found for learner {learner.id} in course {course.slug}"
)
return
for enrollment in enrollments:
for delivery in enrollment.content_deliveries.all():
delivery.delivery_schedules.filter(
status=DeliveryStatus.SCHEDULED
).update(status=DeliveryStatus.CANCELED)
enrollments.update(
status=EnrollmentStatus.DEACTIVATED,
deactivation_reason=DeactivationReason.CANCELED,
final_state_at=timezone.now(),
)