From 18e7c6c77d2df821e4090096a665cc3579fe2a83 Mon Sep 17 00:00:00 2001 From: Tanner Collin Date: Fri, 7 Feb 2020 01:11:09 +0000 Subject: [PATCH] Enforce capitalization of class / session status --- apiserver/apiserver/api/serializers.py | 16 ++++++++-------- apiserver/apiserver/api/views.py | 9 +++++---- apiserver/docs/source/api.rst | 12 ++++++------ apiserver/import_old_portal.py | 3 ++- webclient/src/Classes.js | 10 +++++----- webclient/src/InstructorClasses.js | 24 ++++++++++-------------- 6 files changed, 36 insertions(+), 38 deletions(-) diff --git a/apiserver/apiserver/api/serializers.py b/apiserver/apiserver/api/serializers.py index 24dee73..2bc84ef 100644 --- a/apiserver/apiserver/api/serializers.py +++ b/apiserver/apiserver/api/serializers.py @@ -242,12 +242,12 @@ class CardSerializer(serializers.ModelSerializer): class TrainingSerializer(serializers.ModelSerializer): attendance_status = serializers.ChoiceField([ - 'waiting for payment', - 'withdrawn', - 'rescheduled', - 'no-show', - 'attended', - 'confirmed' + 'Waiting for payment', + 'Withdrawn', + 'Rescheduled', + 'No-show', + 'Attended', + 'Confirmed' ]) session = serializers.PrimaryKeyRelatedField(queryset=models.Session.objects.all()) student_name = serializers.SerializerMethodField() @@ -266,7 +266,7 @@ class TrainingSerializer(serializers.ModelSerializer): class StudentTrainingSerializer(TrainingSerializer): - attendance_status = serializers.ChoiceField(['waiting for payment', 'withdrawn']) + attendance_status = serializers.ChoiceField(['Waiting for payment', 'Withdrawn']) class SessionSerializer(serializers.ModelSerializer): @@ -283,7 +283,7 @@ class SessionSerializer(serializers.ModelSerializer): read_only_fields = ['old_instructor', 'instructor'] def get_student_count(self, obj): - return len([x for x in obj.students.all() if x.attendance_status != 'withdrawn']) + return len([x for x in obj.students.all() if x.attendance_status != 'Withdrawn']) def get_course_name(self, obj): return obj.course.name diff --git a/apiserver/apiserver/api/views.py b/apiserver/apiserver/api/views.py index 72cd3f4..24ac485 100644 --- a/apiserver/apiserver/api/views.py +++ b/apiserver/apiserver/api/views.py @@ -183,6 +183,7 @@ class TrainingViewSet(Base, Retrieve, Create, Update): return serializers.StudentTrainingSerializer # TODO: turn these into @actions + # TODO: check if full def perform_create(self, serializer): session_id = self.request.data['session'] status = self.request.data['attendance_status'] @@ -192,16 +193,16 @@ class TrainingViewSet(Base, Retrieve, Create, Update): raise exceptions.ValidationError('You have already registered') if self.request.user == session.instructor: raise exceptions.ValidationError('You are teaching this session') - if status == 'waiting for payment' and session.cost == 0: - status = 'confirmed' + if status == 'Waiting for payment' and session.cost == 0: + status = 'Confirmed' serializer.save(user=self.request.user, attendance_status=status) def perform_update(self, serializer): session_id = self.request.data['session'] status = self.request.data['attendance_status'] session = get_object_or_404(models.Session, id=session_id) - if status == 'waiting for payment' and session.cost == 0: - status = 'confirmed' + if status == 'Waiting for payment' and session.cost == 0: + status = 'Confirmed' serializer.save(attendance_status=status) diff --git a/apiserver/docs/source/api.rst b/apiserver/docs/source/api.rst index 1e759d2..abccbdf 100644 --- a/apiserver/docs/source/api.rst +++ b/apiserver/docs/source/api.rst @@ -160,7 +160,7 @@ Full User "instructor": null }, "member_id": 1685, - "attendance_status": "confirmed", + "attendance_status": "Confirmed", "sign_up_date": null, "paid_date": null } @@ -530,7 +530,7 @@ Reported Transactions Create Transaction ++++++++++++++++++ -.. http:post:: /transaction/ +.. http:post:: /transactions/ Add a transaction to a member. Admins only. @@ -764,7 +764,7 @@ Training { "id": 971, - "attendance_status": "confirmed", + "attendance_status": "Confirmed", "session": 11073, "student_name": "Tanner Collin", "member_id": 1685, @@ -779,13 +779,13 @@ Training **Users** - :json attendance_status: One of: ``waiting for payment``, ``withdrawn`` + :json attendance_status: One of: ``Waiting for payment``, ``Withdrawn`` :json int session: The session (class) to register for. **Instructors and Admins** - :json attendance_status: One of: ``waiting for payment``, ``withdrawn``, - ``rescheduled``, ``no-show``, ``attended``, ``confirmed`` + :json attendance_status: One of: ``Waiting for payment``, ``Withdrawn``, + ``Rescheduled``, ``No-show``, ``Attended``, ``Confirmed`` :json int session: The session (class) to register for. :requestheader Authorization: ``Token `` diff --git a/apiserver/import_old_portal.py b/apiserver/import_old_portal.py index 9ceba65..9d3c21f 100755 --- a/apiserver/import_old_portal.py +++ b/apiserver/import_old_portal.py @@ -70,7 +70,7 @@ TRAINING_FIELDS = [ 'id', # class_session_id -> session 'member_id', - 'attendance_status', + # attendance_status -> capitalize 'sign_up_date', 'paid_date', ] @@ -239,6 +239,7 @@ for o in old: for f in TRAINING_FIELDS: new[f] = o.__dict__.get(f, None) new['session'] = models.Session.objects.get(id=o.class_session_id) + new['attendance_status'] = o.attendance_status.capitalize() models.Training.objects.create(**new) print('Imported training #{} - {} {}'.format( diff --git a/webclient/src/Classes.js b/webclient/src/Classes.js index 068c064..27159c8 100644 --- a/webclient/src/Classes.js +++ b/webclient/src/Classes.js @@ -90,7 +90,7 @@ export function ClassDetail(props) { const [error, setError] = useState(false); const { token, user, refreshUser } = props; const { id } = useParams(); - const userTraining = user.training.find(x => x.session.id == id); + const userTraining = clazz && clazz.students.find(x => x.user == user.id); useEffect(() => { requester('/sessions/'+id+'/', 'GET', token) @@ -104,7 +104,7 @@ export function ClassDetail(props) { }, [refreshCount]); const handleSignup = () => { - const data = { attendance_status: 'waiting for payment', session: id }; + const data = { attendance_status: 'Waiting for payment', session: id }; requester('/training/', 'POST', token, data) .then(res => { refreshClass(); @@ -190,12 +190,12 @@ export function ClassDetail(props) { (userTraining ?

Status: {userTraining.attendance_status}

- {userTraining.attendance_status === 'withdrawn' ? - : - } diff --git a/webclient/src/InstructorClasses.js b/webclient/src/InstructorClasses.js index bb11ddd..878c104 100644 --- a/webclient/src/InstructorClasses.js +++ b/webclient/src/InstructorClasses.js @@ -9,14 +9,12 @@ import { BasicTable, staticUrl, requester } from './utils.js'; function AttendanceRow(props) { const { student, token, refreshClass } = props; - const [training, setTraining] = useState(student); const [error, setError] = useState(false); const handleMark = (newStatus) => { - const data = { attendance_status: newStatus }; - requester('/training/'+training.id+'/', 'PATCH', token, data) + const data = { ...student, attendance_status: newStatus }; + requester('/training/'+student.id+'/', 'PATCH', token, data) .then(res => { - setTraining(res); refreshClass(); setError(false); }) @@ -26,35 +24,33 @@ function AttendanceRow(props) { }); }; - // 'withdrawn', 'rescheduled', 'no-show', 'attended', 'confirmed' - const makeProps = (name) => ({ onClick: () => handleMark(name), toggle: true, - active: training.attendance_status === name, + active: student.attendance_status === name, }); return (
-

{training.student_name}:

+

{student.student_name}:

- - - - - @@ -104,7 +100,7 @@ function InstructorClassEditor(props) { return (