|
8 | 8 | SendQuizCommand, |
9 | 9 | QuizNotFoundError, |
10 | 10 | ) |
| 11 | +from django_email_learning.services.command_models.send_assignment_command import ( |
| 12 | + SendAssignmentCommand, |
| 13 | + AssignmentNotFoundError, |
| 14 | +) |
11 | 15 | from django_email_learning.jobs.job_metrics import track_job_execution |
12 | 16 | from django_email_learning.services.metrics_service import MetricsService |
13 | 17 | from django_email_learning.models import JobExecution, JobName, JobStatus |
@@ -121,6 +125,24 @@ def process_delivery(self, delivery_schedule: DeliverySchedule) -> None: |
121 | 125 | logger.info( |
122 | 126 | f"Quiz content delivered for DeliverySchedule ID {delivery_schedule.id}. Next content scheduling is deferred until quiz completion." |
123 | 127 | ) |
| 128 | + elif ( |
| 129 | + course_content.type == "assignment" |
| 130 | + and course_content.assignment is not None |
| 131 | + ): |
| 132 | + is_delivered = self.send_assignment_content(delivery_schedule) |
| 133 | + |
| 134 | + # For assignment we don't schedule next content automatically, because the scheduling should be done after assignment completion. |
| 135 | + if is_delivered: |
| 136 | + if not course_content.assignment.is_blocking: |
| 137 | + # reschedule next content immediately for non-blocking assignments, For blocking assignments, the next content will be scheduled after the submission approval. |
| 138 | + logger.info( |
| 139 | + f"Non-blocking assignment content delivered for DeliverySchedule ID {delivery_schedule.id}. Scheduling next content." |
| 140 | + ) |
| 141 | + next_delivery = delivery_schedule.delivery.schedule_next_delivery() |
| 142 | + if next_delivery: |
| 143 | + logger.info( |
| 144 | + f"Scheduled next delivery {next_delivery.id} for enrollment {delivery_schedule.delivery.enrollment.id}" |
| 145 | + ) |
124 | 146 |
|
125 | 147 | def send_lesson_content(self, delivery_schedule: DeliverySchedule) -> bool: |
126 | 148 | if not delivery_schedule.delivery.course_content.lesson: |
@@ -192,6 +214,44 @@ def send_quiz_content(self, delivery_schedule: DeliverySchedule) -> bool: |
192 | 214 | self.handle_failed_delivery(delivery_schedule) |
193 | 215 | return False |
194 | 216 |
|
| 217 | + def send_assignment_content(self, delivery_schedule: DeliverySchedule) -> bool: |
| 218 | + if not delivery_schedule.delivery.course_content.assignment: |
| 219 | + delivery_schedule.status = DeliveryStatus.CANCELED |
| 220 | + delivery_schedule.save() |
| 221 | + logger.error( |
| 222 | + f"DeliverySchedule ID {delivery_schedule.id} has no associated assignment. Canceling the delivery." |
| 223 | + ) |
| 224 | + return False |
| 225 | + |
| 226 | + try: |
| 227 | + if not delivery_schedule.link: |
| 228 | + link = delivery_schedule.generate_link() |
| 229 | + delivery_schedule.link = link |
| 230 | + delivery_schedule.save() |
| 231 | + |
| 232 | + command = SendAssignmentCommand( |
| 233 | + content_id=delivery_schedule.delivery.course_content.id, |
| 234 | + email=delivery_schedule.delivery.enrollment.learner.email, |
| 235 | + link=delivery_schedule.link, |
| 236 | + ) |
| 237 | + command.execute() |
| 238 | + delivery_schedule.status = DeliveryStatus.DELIVERED |
| 239 | + delivery_schedule.save() |
| 240 | + |
| 241 | + return True |
| 242 | + except AssignmentNotFoundError: |
| 243 | + logger.error( |
| 244 | + f"Assignment with ID {delivery_schedule.delivery.course_content.assignment.id} not found. Canceling the delivery." |
| 245 | + ) |
| 246 | + delivery_schedule.status = DeliveryStatus.CANCELED |
| 247 | + delivery_schedule.save() |
| 248 | + except Exception as e: |
| 249 | + logger.exception( |
| 250 | + f"Failed to send assignment content for DeliverySchedule ID {delivery_schedule.id}: {str(e)}" |
| 251 | + ) |
| 252 | + self.handle_failed_delivery(delivery_schedule) |
| 253 | + return False |
| 254 | + |
195 | 255 | def handle_failed_delivery(self, delivery_schedule: DeliverySchedule) -> None: |
196 | 256 | # TODO: Implement custome metric logging for blocked deliveries and failed attempts. |
197 | 257 | """Handle a failed delivery by rescheduling or blocking it.""" |
|
0 commit comments