Auto suggest new class times

master
Tanner Collin 2 years ago
parent ab1a04d800
commit 41f6969a4a
  1. 72
      apiserver/apiserver/api/serializers.py
  2. 9
      webclient/src/InstructorClasses.js

@ -11,7 +11,7 @@ from rest_auth.registration.serializers import RegisterSerializer
from rest_auth.serializers import PasswordChangeSerializer, PasswordResetSerializer, PasswordResetConfirmSerializer, LoginSerializer
from rest_auth.serializers import UserDetailsSerializer
import re
import datetime, time
import datetime, time, calendar
from . import models, fields, utils, utils_ldap, utils_auth, utils_stats
from .. import settings, secrets
@ -528,10 +528,80 @@ class CourseDetailSerializer(serializers.ModelSerializer):
sessions = SessionListSerializer(many=True, read_only=True)
name = serializers.CharField(max_length=100)
description = fields.HTMLField(max_length=6000)
suggestion = serializers.SerializerMethodField()
class Meta:
model = models.Course
fields = '__all__'
def get_suggestion(self, obj):
def iter_dates():
start_of_month = utils.today_alberta_tz().replace(day=1)
for i in range(90):
yield start_of_month + datetime.timedelta(days=i)
def iter_matching_dates(weekday, week_num=False):
week_num_counts = [0] * 13
for date in iter_dates():
if date.weekday() == weekday:
week_num_counts[date.month] += 1
if week_num and week_num_counts[date.month] != week_num:
continue
yield date
def next_date(weekday, week_num=False):
for date in iter_matching_dates(weekday, week_num):
if date > utils.today_alberta_tz():
return date
raise
def course_is_usually_monthly(course):
two_months_ago = utils.today_alberta_tz() - datetime.timedelta(days=61)
recent_sessions = obj.sessions.filter(datetime__gte=two_months_ago)
if recent_sessions.count() < 3:
return True
else:
return False
prev_session = obj.sessions.last()
if obj.id == 273: # monthly clean 10:00 AM 3rd Saturday of each month
date = next_date(calendar.SATURDAY, week_num=3)
time = datetime.time(10, 0)
dt = datetime.datetime.combine(date, time)
dt = utils.TIMEZONE_CALGARY.localize(dt)
cost = 0
max_students = None
elif obj.id == 317: # members' meeting 7:00 PM 3rd Thursday of odd months, Wednesday of even months
if utils.today_alberta_tz().month % 2 == 0:
date = next_date(calendar.WEDNESDAY, week_num=3)
else:
date = next_date(calendar.THURSDAY, week_num=3)
time = datetime.time(19, 0)
dt = datetime.datetime.combine(date, time)
dt = utils.TIMEZONE_CALGARY.localize(dt)
cost = 0
max_students = None
elif prev_session:
prev_session = obj.sessions.last()
dt = prev_session.datetime
if course_is_usually_monthly(obj):
offset_weeks = 4
else:
offset_weeks = 1
dt = dt + datetime.timedelta(weeks=offset_weeks)
five_days_from_now = utils.now_alberta_tz() + datetime.timedelta(days=5)
while dt < five_days_from_now:
dt = dt + datetime.timedelta(weeks=offset_weeks)
cost = prev_session.cost
max_students = prev_session.max_students
else:
return None
return dict(datetime=dt, cost=str(cost), max_students=max_students)
class UserTrainingSerializer(serializers.ModelSerializer):
session = SessionListSerializer()

@ -420,6 +420,11 @@ export function InstructorClassList(props) {
).sort((a, b) => a.datetime > b.datetime ? 1 : -1));
}, [input.datetime]);
const fillSuggestion = (e) => {
e.preventDefault();
setInput({ ...input, ...course.suggestion });
};
return (
<div>
<Header size='medium'>Instructor Panel</Header>
@ -434,6 +439,10 @@ export function InstructorClassList(props) {
<p>Documentation: <a href='https://wiki.protospace.ca/Be_a_Course_Instructor' target='_blank' rel='noopener noreferrer'>https://wiki.protospace.ca/Be_a_Course_Instructor</a></p>
{course.suggestion &&
<p><Button onClick={fillSuggestion}>Suggest</Button> based off previous classes.</p>
}
<InstructorClassEditor input={input} setInput={setInput} error={error} token={token} />
<Form.Button loading={loading} error={error.non_field_errors}>

Loading…
Cancel
Save