From 3c250e5649f2bde197dddfb6234a18b0d8963b87 Mon Sep 17 00:00:00 2001 From: Tyler Hallada Date: Thu, 12 Oct 2017 15:07:04 -0400 Subject: [PATCH] Address Gabe's comments --- .../tests/test_send_recurring_nudge.py | 2 +- openedx/core/djangoapps/schedules/tasks.py | 58 +++++++++++++------ 2 files changed, 40 insertions(+), 20 deletions(-) diff --git a/openedx/core/djangoapps/schedules/management/commands/tests/test_send_recurring_nudge.py b/openedx/core/djangoapps/schedules/management/commands/tests/test_send_recurring_nudge.py index 049f519f5f..fddf199aa4 100644 --- a/openedx/core/djangoapps/schedules/management/commands/tests/test_send_recurring_nudge.py +++ b/openedx/core/djangoapps/schedules/management/commands/tests/test_send_recurring_nudge.py @@ -150,7 +150,7 @@ class TestSendRecurringNudge(FilteredQueryCountMixin, CacheIsolationTestCase): enrollment__user=user1, ) schedule.enrollment.course = CourseOverviewFactory() - schedule.enrollment.course.end = datetime.datetime.now() - datetime.timedelta(days=1) + schedule.enrollment.course.end = datetime.datetime.now(pytz.UTC) - datetime.timedelta(days=1) test_time = datetime.datetime(2017, 8, 3, 20, tzinfo=pytz.UTC) test_time_str = serialize(test_time) diff --git a/openedx/core/djangoapps/schedules/tasks.py b/openedx/core/djangoapps/schedules/tasks.py index 018d2b2d8d..c746fe1247 100644 --- a/openedx/core/djangoapps/schedules/tasks.py +++ b/openedx/core/djangoapps/schedules/tasks.py @@ -90,12 +90,15 @@ def _recurring_nudge_schedule_send(site_id, msg_str): def recurring_nudge_schedule_bin( site_id, target_day_str, day_offset, bin_num, org_list, exclude_orgs=False, override_recipient_email=None, ): - target_day = deserialize(target_day_str) + target_date = deserialize(target_day_str) + # TODO: in the next refactor of this task, pass in current_date instead of reproducing it here + current_date = target_date - datetime.timedelta(days=day_offset) msg_type = RecurringNudge(abs(day_offset)) for (user, language, context) in _recurring_nudge_schedules_for_bin( Site.objects.get(id=site_id), - target_day, + current_date, + target_date, bin_num, org_list, exclude_orgs @@ -111,11 +114,11 @@ def recurring_nudge_schedule_bin( _recurring_nudge_schedule_send.apply_async((site_id, str(msg)), retry=False) -def _recurring_nudge_schedules_for_bin(site, target_day, bin_num, org_list, exclude_orgs=False): - beginning_of_day = target_day.replace(hour=0, minute=0, second=0, microsecond=0) +def _recurring_nudge_schedules_for_bin(site, current_date, target_date, bin_num, org_list, exclude_orgs=False): schedules = get_schedules_with_target_date_by_bin_and_orgs( schedule_date_field='start', - target_date=beginning_of_day, + current_date=current_date, + target_date=target_date, bin_num=bin_num, num_bins=RECURRING_NUDGE_NUM_BINS, org_list=org_list, @@ -154,12 +157,15 @@ class UpgradeReminder(ScheduleMessageType): def upgrade_reminder_schedule_bin( site_id, target_day_str, day_offset, bin_num, org_list, exclude_orgs=False, override_recipient_email=None, ): - target_day = deserialize(target_day_str) + target_date = deserialize(target_day_str) + # TODO: in the next refactor of this task, pass in current_date instead of reproducing it here + current_date = target_date - datetime.timedelta(days=day_offset) msg_type = UpgradeReminder() for (user, language, context) in _upgrade_reminder_schedules_for_bin( Site.objects.get(id=site_id), - target_day, + current_date, + target_date, bin_num, org_list, exclude_orgs @@ -185,12 +191,11 @@ def _upgrade_reminder_schedule_send(site_id, msg_str): ace.send(msg) -def _upgrade_reminder_schedules_for_bin(site, target_day, bin_num, org_list, exclude_orgs=False): - beginning_of_day = target_day.replace(hour=0, minute=0, second=0, microsecond=0) - +def _upgrade_reminder_schedules_for_bin(site, current_date, target_date, bin_num, org_list, exclude_orgs=False): schedules = get_schedules_with_target_date_by_bin_and_orgs( schedule_date_field='upgrade_deadline', - target_date=beginning_of_day, + current_date=current_date, + target_date=target_date, bin_num=bin_num, num_bins=RECURRING_NUDGE_NUM_BINS, org_list=org_list, @@ -227,6 +232,7 @@ def _upgrade_reminder_schedules_for_bin(site, target_day, bin_num, org_list, exc yield (user, first_schedule.enrollment.course.language, template_context) +<<<<<<< HEAD class CourseUpdate(ScheduleMessageType): pass @@ -319,23 +325,30 @@ def get_course_week_summary(course_id, week_num): def get_schedules_with_target_date_by_bin_and_orgs(schedule_date_field, target_date, bin_num, num_bins=DEFAULT_NUM_BINS, org_list=None, exclude_orgs=False, order_by='enrollment__user__id'): +||||||| parent of c6f507c4b7... Address Gabe's comments +def get_schedules_with_target_date_by_bin_and_orgs(schedule_date_field, target_date, bin_num, num_bins=DEFAULT_NUM_BINS, + org_list=None, exclude_orgs=False): +======= +def get_schedules_with_target_date_by_bin_and_orgs(schedule_date_field, current_date, target_date, bin_num, + num_bins=DEFAULT_NUM_BINS, org_list=None, exclude_orgs=False): +>>>>>>> c6f507c4b7... Address Gabe's comments """ Returns Schedules with the target_date, related to Users whose id matches the bin_num, and filtered by org_list. Arguments: schedule_date_field -- string field name to query on the User's Schedule model - target_date -- datetime day (with zeroed-out time) that the User's Schedule's schedule_date_field value should fall - under + current_date -- datetime that will be used as "right now" in the query + target_date -- datetime that the User's Schedule's schedule_date_field value should fall under bin_num -- int for selecting the bin of Users whose id % num_bins == bin_num num_bin -- int specifying the number of bins to separate the Users into (default: DEFAULT_NUM_BINS) org_list -- list of course_org names (strings) that the returned Schedules must or must not be in (default: None) exclude_orgs -- boolean indicating whether the returned Schedules should exclude (True) the course_orgs in org_list or strictly include (False) them (default: False) """ - today = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) + target_day = _get_datetime_beginning_of_day(target_date) schedule_date_equals_target_date_filter = { - 'courseenrollment__schedule__{}__gte'.format(schedule_date_field): target_date, - 'courseenrollment__schedule__{}__lt'.format(schedule_date_field): target_date + datetime.timedelta(days=1), + 'courseenrollment__schedule__{}__gte'.format(schedule_date_field): target_day, + 'courseenrollment__schedule__{}__lt'.format(schedule_date_field): target_day + datetime.timedelta(days=1), } users = User.objects.filter( courseenrollment__is_active=True, @@ -347,8 +360,8 @@ def get_schedules_with_target_date_by_bin_and_orgs(schedule_date_field, target_d ) schedule_date_equals_target_date_filter = { - '{}__gte'.format(schedule_date_field): target_date, - '{}__lt'.format(schedule_date_field): target_date + datetime.timedelta(days=1), + '{}__gte'.format(schedule_date_field): target_day, + '{}__lt'.format(schedule_date_field): target_day + datetime.timedelta(days=1), } schedules = Schedule.objects.select_related( 'enrollment__user__profile', @@ -356,7 +369,7 @@ def get_schedules_with_target_date_by_bin_and_orgs(schedule_date_field, target_d ).prefetch_related( 'enrollment__course__modes' ).filter( - Q(enrollment__course__end__isnull=True) | Q(enrollment__course__end__gte=today), + Q(enrollment__course__end__isnull=True) | Q(enrollment__course__end__gte=current_date), enrollment__user__in=users, enrollment__is_active=True, **schedule_date_equals_target_date_filter @@ -401,3 +414,10 @@ def _get_link_to_purchase_verified_certificate(a_user, a_schedule): return None return verified_upgrade_deadline_link(a_user, enrollment.course) + + +def _get_datetime_beginning_of_day(dt): + """ + Truncates hours, minutes, seconds, and microseconds to zero on given datetime. + """ + return dt.replace(hour=0, minute=0, second=0, microsecond=0)