From ecd88318264884d79b7c90277b80579e96ed4ce8 Mon Sep 17 00:00:00 2001
From: Piotr Gawron <piotr.gawron@uni.lu>
Date: Wed, 13 Sep 2017 18:40:06 +0200
Subject: [PATCH] redcap notifications in the web client

---
 smash/web/redcap_connector.py                 |  9 +--
 .../redcap/inconsistent_subjects.html         | 71 +++++++++++++++++++
 .../templates/redcap/missing_subjects.html    | 71 +++++++++++++++++++
 smash/web/urls.py                             |  7 ++
 smash/web/views/__init__.py                   |  1 +
 smash/web/views/notifications.py              | 30 +++++++-
 smash/web/views/redcap.py                     | 33 +++++++++
 7 files changed, 217 insertions(+), 5 deletions(-)
 create mode 100644 smash/web/templates/redcap/inconsistent_subjects.html
 create mode 100644 smash/web/templates/redcap/missing_subjects.html
 create mode 100644 smash/web/views/redcap.py

diff --git a/smash/web/redcap_connector.py b/smash/web/redcap_connector.py
index 959c56aa..706c4e19 100644
--- a/smash/web/redcap_connector.py
+++ b/smash/web/redcap_connector.py
@@ -83,12 +83,12 @@ class RedcapConnector(object):
 
         result = []
         for subject in red_cap_subjects:
-            if getattr(smash_subject_by_nd, subject.nd_number, None) is None:
+            if smash_subject_by_nd.get(subject.nd_number) is None:
                 url = self.create_redcap_link(pid, redcap_version, subject)
                 result.append(MissingSubject.create(red_cap_subject=subject, smash_subject=None, url=url))
 
         for subject in smash_subjects:
-            if getattr(red_cap_subject_by_nd, subject.nd_number, None) is None:
+            if red_cap_subject_by_nd.get(subject.nd_number) is None:
                 result.append(MissingSubject.create(red_cap_subject=None, smash_subject=subject))
 
         return result
@@ -137,8 +137,8 @@ class RedcapConnector(object):
         self.add_missing(missing)
 
     def refresh_inconsistent(self):
-        missing = self.find_inconsistent()
-        self.add_inconsistent(missing)
+        inconsistent = self.find_inconsistent()
+        self.add_inconsistent(inconsistent)
 
     def find_inconsistent(self):
         pid = self.get_project_id()
@@ -154,6 +154,7 @@ class RedcapConnector(object):
         result = []
         for subject in smash_subjects:
             red_cap_subject = red_cap_subject_by_nd.get(subject.nd_number)
+
             if red_cap_subject is not None:
                 url = self.create_redcap_link(pid, redcap_version, subject)
                 subject = self.create_inconsistency_subject(red_cap_subject, subject, url)
diff --git a/smash/web/templates/redcap/inconsistent_subjects.html b/smash/web/templates/redcap/inconsistent_subjects.html
new file mode 100644
index 00000000..e436c11e
--- /dev/null
+++ b/smash/web/templates/redcap/inconsistent_subjects.html
@@ -0,0 +1,71 @@
+{% extends "_base.html" %}
+{% load static %}
+
+{% block styles %}
+    {{ block.super }}
+    <!-- DataTables -->
+    <link rel="stylesheet" href="{% static 'AdminLTE/plugins/datatables/dataTables.bootstrap.css' %}">
+{% endblock styles %}
+
+{% block ui_active_tab %}'subjects'{% endblock ui_active_tab %}
+{% block page_header %}Missing subjects{% endblock page_header %}
+{% block page_description %}{% endblock page_description %}
+
+{% block breadcrumb %}
+    {% include "subjects/breadcrumb.html" %}
+{% endblock breadcrumb %}
+
+{% block maincontent %}
+
+    <div class="box-body">
+        <table id="table" class="table table-bordered table-striped">
+            <thead>
+            <tr>
+                <th>Smash subject</th>
+                <th>RED Cap subject</th>
+                <th>Differences</th>
+            </tr>
+            </thead>
+            <tbody>
+            {% for inconsistent_subject in inconsistent_subjects %}
+                <tr>
+                    <td>
+                        <a href="{% url 'web.views.subject_edit' inconsistent_subject.subject.id %}">{{ inconsistent_subject.subject }}</a>
+                    </td>
+                    <td>
+                        <a href="{{ inconsistent_subject.redcap_url }}"
+                           target="_redcap">{{ inconsistent_subject.subject.nd_number }}</a>
+                    </td>
+                    <td>
+                        <ul>
+                            {% for field in inconsistent_subject.inconsistentfield_set.all %}
+                                <li>{{ field.name }}: {{ field.smash_value }} - {{ field.redcap_value }}</li>
+                            {% endfor %}
+                        </ul>
+                    </td>
+                </tr>
+            {% endfor %}
+
+            </tbody>
+        </table>
+    </div>
+{% endblock maincontent %}
+
+{% block scripts %}
+    {{ block.super }}
+
+    <script src="{% static 'AdminLTE/plugins/datatables/jquery.dataTables.min.js' %}"></script>
+    <script src="{% static 'AdminLTE/plugins/datatables/dataTables.bootstrap.min.js' %}"></script>
+    <script>
+        $(function () {
+            $('#table').DataTable({
+                "paging": true,
+                "lengthChange": false,
+                "searching": true,
+                "ordering": true,
+                "info": true,
+                "autoWidth": false
+            });
+        });
+    </script>
+{% endblock scripts %}
diff --git a/smash/web/templates/redcap/missing_subjects.html b/smash/web/templates/redcap/missing_subjects.html
new file mode 100644
index 00000000..855df575
--- /dev/null
+++ b/smash/web/templates/redcap/missing_subjects.html
@@ -0,0 +1,71 @@
+{% extends "_base.html" %}
+{% load static %}
+
+{% block styles %}
+    {{ block.super }}
+    <!-- DataTables -->
+    <link rel="stylesheet" href="{% static 'AdminLTE/plugins/datatables/dataTables.bootstrap.css' %}">
+{% endblock styles %}
+
+{% block ui_active_tab %}'subjects'{% endblock ui_active_tab %}
+{% block page_header %}Missing subjects{% endblock page_header %}
+{% block page_description %}{% endblock page_description %}
+
+{% block breadcrumb %}
+    {% include "subjects/breadcrumb.html" %}
+{% endblock breadcrumb %}
+
+{% block maincontent %}
+
+    <div class="box-body">
+        <table id="table" class="table table-bordered table-striped">
+            <thead>
+            <tr>
+                <th>ND number</th>
+                <th>Smash subject</th>
+                <th>RED Cap subject</th>
+                <th>Ignored</th>
+            </tr>
+            </thead>
+            <tbody>
+            {% for missing_subject in missing_subjects %}
+                <tr>
+                    <td>{% if missing_subject.subject %}
+                        {{ missing_subject.subject.nd_number }} {% elif missing_subject.redcap_id %}
+                        {{ missing_subject.redcap_id }} {% endif %}</td>
+                    <td>{% if missing_subject.subject %}
+                        <a href="{% url 'web.views.subject_edit' missing_subject.subject.id %}">{{ missing_subject.subject }}</a>
+                    {% endif %}
+                    </td>
+                    <td>{% if missing_subject.redcap_id %}
+                        <a href="{{ missing_subject.redcap_url }}" target="_redcap">{{ missing_subject.redcap_id }}</a> {% endif %}
+                    </td>
+                    <td>
+                        {% if missing_subject.ignore %}YES{% else %}NO{% endif %}
+                    </td>
+                </tr>
+            {% endfor %}
+
+            </tbody>
+        </table>
+    </div>
+{% endblock maincontent %}
+
+{% block scripts %}
+    {{ block.super }}
+
+    <script src="{% static 'AdminLTE/plugins/datatables/jquery.dataTables.min.js' %}"></script>
+    <script src="{% static 'AdminLTE/plugins/datatables/dataTables.bootstrap.min.js' %}"></script>
+    <script>
+        $(function () {
+            $('#table').DataTable({
+                "paging": true,
+                "lengthChange": false,
+                "searching": true,
+                "ordering": true,
+                "info": true,
+                "autoWidth": false
+            });
+        });
+    </script>
+{% endblock scripts %}
diff --git a/smash/web/urls.py b/smash/web/urls.py
index 6247a094..55216a04 100644
--- a/smash/web/urls.py
+++ b/smash/web/urls.py
@@ -76,6 +76,13 @@ urlpatterns = [
         name='web.views.subject_visit_details'),
     url(r'^subjects/edit/(?P<id>\d+)$', views.subject.subject_edit, name='web.views.subject_edit'),
 
+    #########################
+    # RED CAP NOTIFICATIONS #
+    #########################
+
+    url(r'^redcap/missing_subjects$', views.redcap.missing_subjects, name='web.views.missing_redcap_subject'),
+    url(r'^redcap/inconsistent_subjects$', views.redcap.inconsistent_subjects, name='web.views.inconsistent_redcap_subject'),
+
     ####################
     #    CONTACTS      #
     ####################
diff --git a/smash/web/views/__init__.py b/smash/web/views/__init__.py
index 49fc1dce..0afadd68 100644
--- a/smash/web/views/__init__.py
+++ b/smash/web/views/__init__.py
@@ -72,3 +72,4 @@ import export
 import contact_attempt
 import configuration_item
 import language
+import redcap
diff --git a/smash/web/views/notifications.py b/smash/web/views/notifications.py
index 6a580bc5..8dd49b02 100644
--- a/smash/web/views/notifications.py
+++ b/smash/web/views/notifications.py
@@ -5,7 +5,7 @@ from django.utils import timezone
 from django.contrib.auth.models import User, AnonymousUser
 from django.db.models import Count, Case, When
 
-from ..models import Worker, Subject, Visit, Appointment, Location
+from ..models import Worker, Subject, Visit, Appointment, Location, MissingSubject, InconsistentSubject
 
 
 class NotificationCount(object):
@@ -30,6 +30,24 @@ def get_exceeded_visit_notifications_count(user):
     return notification
 
 
+def get_missing_redcap_subject_notification_count(user):
+    notification = NotificationCount(
+        title="missing RED Cap subject",
+        count=get_missing_redcap_subjects(user).count(),
+        style="fa fa-user text-yellow",
+        type='web.views.missing_redcap_subject')
+    return notification
+
+
+def get_inconsistent_redcap_subject_notification_count(user):
+    notification = NotificationCount(
+        title="inconsistent RED Cap subject",
+        count=get_inconsistent_redcap_subjects(user).count(),
+        style="fa fa-user-circle text-yellow",
+        type='web.views.inconsistent_redcap_subject')
+    return notification
+
+
 def get_subjects_with_reminder_count(user):
     notification = NotificationCount(
         title="subject required contact",
@@ -105,6 +123,8 @@ def get_notifications(the_user):
         notifications.append(get_subject_with_no_visit_notifications_count(worker))
         notifications.append(get_approaching_visits_for_mail_contact_count(worker))
         notifications.append(get_subjects_with_reminder_count(worker))
+        notifications.append(get_missing_redcap_subject_notification_count(worker))
+        notifications.append(get_inconsistent_redcap_subject_notification_count(worker))
 
         for notification in notifications:
             count += notification.count
@@ -184,6 +204,14 @@ def get_exceeded_visits(user):
                                 ).order_by('datetime_begin')
 
 
+def get_missing_redcap_subjects(user):
+    return MissingSubject.objects.all().order_by("ignore")
+
+
+def get_inconsistent_redcap_subjects(user):
+    return InconsistentSubject.objects.all()
+
+
 def get_unfinished_appointments(user):
     return Appointment.objects.filter(
         datetime_when__lt=get_today_midnight_date(),
diff --git a/smash/web/views/redcap.py b/smash/web/views/redcap.py
new file mode 100644
index 00000000..60e57dd8
--- /dev/null
+++ b/smash/web/views/redcap.py
@@ -0,0 +1,33 @@
+# coding=utf-8
+
+from django.contrib import messages
+
+from notifications import get_missing_redcap_subjects, get_inconsistent_redcap_subjects
+from . import wrap_response
+from ..redcap_connector import RedcapConnector
+
+
+def missing_subjects(request):
+    connector = RedcapConnector()
+    if connector.is_valid():
+        connector.refresh_missing()
+    else:
+        messages.add_message(request, messages.ERROR, 'There is a problem with RED Cap connection')
+
+    context = {
+        'missing_subjects': get_missing_redcap_subjects(request.user)
+    }
+    return wrap_response(request, 'redcap/missing_subjects.html', context)
+
+
+def inconsistent_subjects(request):
+    connector = RedcapConnector()
+    if connector.is_valid():
+        connector.refresh_inconsistent()
+    else:
+        messages.add_message(request, messages.ERROR, 'There is a problem with RED Cap connection')
+
+    context = {
+        'inconsistent_subjects': get_inconsistent_redcap_subjects(request.user)
+    }
+    return wrap_response(request, 'redcap/inconsistent_subjects.html', context)
-- 
GitLab