Repository: ocadotechnology/codeforlife-portal

Issue:
Method checking onboarding completion needs optimising
Currently, the onboarding process is considered done if:
- the teacher has created an account and
- the teacher has created/joined a school and
- the teacher has created at least one class and
- the teacher has added at least one student to their **first** class.

This causes an issue because in the case where a teacher has two classes, and moves all their students to their second class, their first class will be empty, and the onboarding process will revert to incomplete (as the fourth condition will not be met). This will cause the teacher to be redirected to the 'add students' section of the onboarding process upon login.

Possible improvement: check if there if there is one student in any of the classes a teacher has. However this still isn't perfect because even if a teacher transfers/releases all their students, this condition still won't be satisfied, and at this point the teacher shouldn't be sent back to the onboarding process. 


Discussion:
As discussed, a Boolean field in the Teacher model seems appropriate!
So, actually, we won't add a field. We will check:
if no school:
__onboarding
else:
__if 0 class:
____onboarding
__elif 1 class:
____if 0 student:
______onboarding
____else:
______dashboard
__else:
____dashboard

Resolving patch:
diff --git a/portal/models.py b/portal/models.py
--- a/portal/models.py
+++ b/portal/models.py
@@ -126,12 +126,6 @@ def teaches(self, userprofile):
     def has_school(self):
         return self.school is not (None or "")
 
-    def first_class(self):
-        classes = self.class_teacher.all()
-        if classes:
-            return classes[0]
-        return None
-
     def __unicode__(self):
         return '%s %s' % (self.new_user.first_name, self.new_user.last_name)
 
diff --git a/portal/templatetags/app_tags.py b/portal/templatetags/app_tags.py
--- a/portal/templatetags/app_tags.py
+++ b/portal/templatetags/app_tags.py
@@ -42,27 +42,33 @@
 
 register = template.Library()
 
+
 @register.filter(name='emaildomain')
 @stringfilter
 def emaildomain(email):
     return '*********' + email[email.find('@'):]
 
+
 @register.filter(name='has_2FA')
 def has_2FA(u):
     return using_two_factor(u)
 
+
 @register.filter(name='is_logged_in')
 def is_logged_in(u):
     return u.is_authenticated() and (not using_two_factor(u) or (hasattr(u, 'is_verified') and u.is_verified()))
 
+
 @register.filter
 def is_developer(u):
     return not u.is_anonymous() and u.userprofile.developer
 
+
 @register.filter
 def has_beta_access(request):
     return beta.has_beta_access(request)
 
+
 @register.filter(name='make_into_username')
 def make_into_username(u):
     username = ''
@@ -74,30 +80,37 @@ def make_into_username(u):
 
     return username
 
+
 @register.filter(name='truncate')
 def truncate(s, max_length=20):
     if len(s) > max_length:
         s = s[:max(0, max_length-3)] + '...'
     return s
 
+
 @register.filter(name='is_logged_in_as_teacher')
 def is_logged_in_as_teacher(u):
     return is_logged_in(u) and u.userprofile and hasattr(u.userprofile, 'teacher')
 
+
 @register.filter(name='has_teacher_finished_onboarding')
 def has_teacher_finished_onboarding(u):
     teacher = u.userprofile.teacher
-    class_ = teacher.first_class()
-    return is_logged_in_as_teacher(u) and teacher.has_school() and class_ is not None and class_.has_students()
+    classes = teacher.class_teacher.all()
+    return is_logged_in_as_teacher(u) and teacher.has_school() and classes and (classes.count() > 1 or
+                                                                                classes[0].has_students())
+
 
 @register.filter(name='is_logged_in_as_student')
 def is_logged_in_as_student(u):
     return is_logged_in(u) and u.userprofile and hasattr(u.userprofile, 'student')
 
+
 @register.filter(name='is_logged_in_as_school_user')
 def is_logged_in_as_school_user(u):
     return is_logged_in(u) and u.userprofile and ((hasattr(u.userprofile, 'student') and u.userprofile.student.class_field != None) or hasattr(u.userprofile, 'teacher'))
 
+
 @register.filter(name='make_title_caps')
 def make_title_caps(s):
     if len(s) <= 0:
@@ -106,6 +119,7 @@ def make_title_caps(s):
         s = s[0].upper() + s[1:]
     return s
 
+
 @register.filter(name='get_user_status')
 def get_user_status(u):
     if is_logged_in_as_school_user(u):
@@ -119,6 +133,7 @@ def get_user_status(u):
         return 'UNTRACKED'
     return 'UNTRACKED'
 
+
 @register.filter(name='cloud_storage')
 @stringfilter
 def cloud_storage(e):
diff --git a/portal/views/home_new.py b/portal/views/home_new.py
--- a/portal/views/home_new.py
+++ b/portal/views/home_new.py
@@ -335,12 +335,12 @@ def redirect_user_to_correct_page(teacher):
     if teacher.has_school():
         classes = teacher.class_teacher.all()
         if classes:
-            first_class = teacher.first_class()
-
-            if first_class.has_students():
+            classes_count = classes.count()
+            if classes_count > 1 or classes[0].has_students():
                 return HttpResponseRedirect(reverse_lazy('dashboard'))
             else:
-                return HttpResponseRedirect(reverse_lazy('onboarding-class', kwargs={'access_code': first_class.access_code}))
+                return HttpResponseRedirect(reverse_lazy('onboarding-class',
+                                                         kwargs={'access_code': classes[0].access_code}))
         else:
             return HttpResponseRedirect(reverse_lazy('onboarding-classes'))
     else:


Test patch: