From 6060c7b147bbcace8dce0c65c14d0e14de1c6f9e Mon Sep 17 00:00:00 2001
From: Carlos Vega <carlos.vega@.uni.lu>
Date: Thu, 27 Sep 2018 16:18:54 +0200
Subject: [PATCH] Issue #207 . Added custom sorting for screening field in
 study subject based on the filter introduced in the column. Multivalues are
 re-sorted

---
 smash/web/api_views/subject.py               | 10 +++++++---
 smash/web/models/study_subject.py            | 14 ++++++++++++++
 smash/web/tests/functions.py                 | 11 +++++++++++
 smash/web/tests/models/test_study_subject.py | 19 ++++++++++++++++++-
 4 files changed, 50 insertions(+), 4 deletions(-)

diff --git a/smash/web/api_views/subject.py b/smash/web/api_views/subject.py
index 0d089e23..cd16200b 100644
--- a/smash/web/api_views/subject.py
+++ b/smash/web/api_views/subject.py
@@ -97,7 +97,7 @@ def order_by_visit(subjects_to_be_ordered, order_direction, visit_number):
         order_direction + 'sort_visit_date')
 
 
-def get_subjects_order(subjects_to_be_ordered, order_column, order_direction):
+def get_subjects_order(subjects_to_be_ordered, order_column, order_direction, column_filters={}):
     result = subjects_to_be_ordered
     if order_direction == "asc":
         order_direction = ""
@@ -112,7 +112,11 @@ def get_subjects_order(subjects_to_be_ordered, order_column, order_direction):
     elif order_column == "referral":
         result = subjects_to_be_ordered.order_by(order_direction + 'referral')
     elif order_column == "screening_number":
-        result = subjects_to_be_ordered.order_by(order_direction + 'screening_number')
+        if u'screening_number' not in column_filters:
+            result = subjects_to_be_ordered.order_by(order_direction + 'screening_number')
+        else:
+             result = subjects_to_be_ordered.all()
+             result = sorted(result, key=lambda t: t.sort_matched_screening_first(column_filters[u'screening_number']), reverse = order_direction == '-' )
     elif order_column == "default_location":
         result = subjects_to_be_ordered.order_by(order_direction + 'default_location')
     elif order_column == "flying_team":
@@ -284,7 +288,7 @@ def subjects(request, type):
         count = all_subjects.count()
 
         filtered_subjects = get_subjects_filtered(all_subjects, filters)
-        ordered_subjects = get_subjects_order(filtered_subjects, order_column, order_dir)
+        ordered_subjects = get_subjects_order(filtered_subjects, order_column, order_dir, column_filters=dict(filters))
         sliced_subjects = ordered_subjects[start:(start + length)]
 
         result_subjects = sliced_subjects
diff --git a/smash/web/models/study_subject.py b/smash/web/models/study_subject.py
index 7963fe5f..dae313c2 100644
--- a/smash/web/models/study_subject.py
+++ b/smash/web/models/study_subject.py
@@ -156,6 +156,20 @@ class StudySubject(models.Model):
                                      verbose_name='Resign reason'
                                      )
 
+    def sort_matched_screening_first(self, pattern):
+        if pattern is None:
+            return self.screening_number
+        
+        words = self.screening_number.split(';')
+        matches, reminder = [], []
+        for word in words:
+            if pattern in word:
+                matches.append(word.strip())
+            else:
+                reminder.append(word.strip())
+
+        return '; '.join(matches + reminder)
+            
     def __str__(self):
         return "%s %s" % (self.subject.first_name, self.subject.last_name)
 
diff --git a/smash/web/tests/functions.py b/smash/web/tests/functions.py
index fbb6a991..3af08171 100644
--- a/smash/web/tests/functions.py
+++ b/smash/web/tests/functions.py
@@ -197,6 +197,17 @@ def create_study_subject(subject_id=1, subject=None):
         subject=subject
     )
 
+def create_study_subject_with_multiple_screening_numbers(subject_id=1, subject=None):
+    if subject is None:
+        subject = create_subject()
+    return StudySubject.objects.create(
+        default_location=get_test_location(),
+        type=SUBJECT_TYPE_CHOICES_CONTROL,
+        screening_number='E-00{}; L-00{}'.format(subject_id, subject_id),
+        study=get_test_study(),
+        subject=subject
+    )
+
 
 def create_red_cap_subject():
     result = RedcapSubject()
diff --git a/smash/web/tests/models/test_study_subject.py b/smash/web/tests/models/test_study_subject.py
index cebd56b7..dc41b3b6 100644
--- a/smash/web/tests/models/test_study_subject.py
+++ b/smash/web/tests/models/test_study_subject.py
@@ -2,7 +2,7 @@ from django.test import TestCase
 
 from web.models import Appointment
 from web.models import Visit
-from web.tests.functions import create_study_subject, create_appointment
+from web.tests.functions import create_study_subject, create_appointment, create_study_subject_with_multiple_screening_numbers
 from web.tests.functions import create_visit
 
 
@@ -19,3 +19,20 @@ class SubjectModelTests(TestCase):
         self.assertTrue(subject.resigned)
         self.assertTrue(visit_finished)
         self.assertEquals(Appointment.APPOINTMENT_STATUS_CANCELLED, appointment_status)
+
+    def test_sort_matched_screening_first(self):
+        subject = create_study_subject_with_multiple_screening_numbers(subject_id=1)
+        self.assertEqual(subject.sort_matched_screening_first('L'), 'L-00{}; E-00{}'.format(1, 1))
+        self.assertEqual(subject.sort_matched_screening_first('L-00'), 'L-00{}; E-00{}'.format(1, 1))
+        self.assertEqual(subject.sort_matched_screening_first('E'), 'E-00{}; L-00{}'.format(1, 1))
+        self.assertEqual(subject.sort_matched_screening_first('-'), 'E-00{}; L-00{}'.format(1, 1))
+        self.assertEqual(subject.sort_matched_screening_first(''), 'E-00{}; L-00{}'.format(1, 1))
+        self.assertEqual(subject.sort_matched_screening_first('001'), 'E-00{}; L-00{}'.format(1, 1))
+        self.assertEqual(subject.sort_matched_screening_first('00'), 'E-00{}; L-00{}'.format(1, 1))
+        self.assertEqual(subject.sort_matched_screening_first('potato'), 'E-00{}; L-00{}'.format(1, 1))
+        subject = create_study_subject(subject_id=1)
+        self.assertEqual(subject.sort_matched_screening_first('pi'), "piotr's number" + str(1))
+        self.assertEqual(subject.sort_matched_screening_first(''), "piotr's number" + str(1))
+        self.assertEqual(subject.sort_matched_screening_first('potato'), "piotr's number" + str(1))
+        self.assertEqual(subject.sort_matched_screening_first('num'), "piotr's number" + str(1))
+        
\ No newline at end of file
-- 
GitLab