diff --git a/.gitignore b/.gitignore index 1fca780f5c3f8f1e9b49800d437720d5a6397ea7..7230e12f66c4c676e29c1c6a86a1fbaa7aaedd4c 100644 --- a/.gitignore +++ b/.gitignore @@ -21,6 +21,7 @@ appointment-import/tmp.sql out .idea smash/smash.log +smash/smash/smash.log .coverage diff --git a/smash/web/migrations/0054_remove_inconsistentsubject_ignore.py b/smash/web/migrations/0054_remove_inconsistentsubject_ignore.py new file mode 100644 index 0000000000000000000000000000000000000000..e0e4de83c12b6aedd6a67419e3413d7206aa5a16 --- /dev/null +++ b/smash/web/migrations/0054_remove_inconsistentsubject_ignore.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.7 on 2017-09-13 15:33 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('web', '0053_auto_20170913_0948'), + ] + + operations = [ + migrations.RemoveField( + model_name='inconsistentsubject', + name='ignore', + ), + ] diff --git a/smash/web/models/inconsistent_subject.py b/smash/web/models/inconsistent_subject.py index 590388fd37b3835fa8adfe6deab63ab459575334..b9298c515b5d7dead50cecf5d02c94615be5d8e1 100644 --- a/smash/web/models/inconsistent_subject.py +++ b/smash/web/models/inconsistent_subject.py @@ -44,11 +44,6 @@ class InconsistentSubject(models.Model): class Meta: app_label = 'web' - ignore = models.BooleanField( - default=False, - verbose_name='Ignore missing subject' - ) - subject = models.ForeignKey("web.Subject", verbose_name='Subject', null=True, diff --git a/smash/web/redcap_connector.py b/smash/web/redcap_connector.py index 586bd701d372aedee03c5340611d20ef5c589c2d..959c56aa3c475ba04df6482abdf5803c8f3d89be 100644 --- a/smash/web/redcap_connector.py +++ b/smash/web/redcap_connector.py @@ -1,16 +1,16 @@ # coding=utf-8 -import logging -import pycurl, cStringIO -import certifi +import cStringIO import json +import logging +import pycurl -from web.models.missing_subject import MissingSubject -from web.models.inconsistent_subject import InconsistentField, InconsistentSubject +import certifi from web.models import ConfigurationItem, Subject, Language - from web.models.constants import REDCAP_TOKEN_CONFIGURATION_TYPE, \ - REDCAP_BASE_URL_CONFIGURATION_TYPE, SEX_CHOICES_MALE, SEX_CHOICES_FEMALE + REDCAP_BASE_URL_CONFIGURATION_TYPE +from web.models.inconsistent_subject import InconsistentField, InconsistentSubject +from web.models.missing_subject import MissingSubject RED_CAP_LANGUAGE_4_FIELD = 'dm_language_4' @@ -93,6 +93,53 @@ class RedcapConnector(object): return result + @staticmethod + def add_missing(missing_subjects): + MissingSubject.objects.filter(ignore=False).delete() + ignored_missing_subjects = MissingSubject.objects.all() + ignored_redcap_by_nd_number = {} + ignored_smash_by_nd_number = {} + for missing_subject in ignored_missing_subjects: + if missing_subject.redcap_id is not None: + ignored_redcap_by_nd_number[missing_subject.redcap_id] = missing_subject + if missing_subject.subject is not None: + ignored_smash_by_nd_number[missing_subject.subject.nd_number] = missing_subject + + for missing_subject in missing_subjects: + ignored = False + if missing_subject.redcap_id is not None and ignored_redcap_by_nd_number.get( + missing_subject.redcap_id) is not None: + ignored = True + if missing_subject.subject is not None and ignored_smash_by_nd_number.get( + missing_subject.subject.nd_number) is not None: + ignored = True + if not ignored: + MissingSubject.objects.create(subject=missing_subject.subject, redcap_id=missing_subject.redcap_id, + redcap_url=missing_subject.redcap_url) + + @staticmethod + def add_inconsistent(inconsistent_subjects): + InconsistentField.objects.all().delete() + InconsistentSubject.objects.all().delete() + + for inconsistent_subject in inconsistent_subjects: + subject = InconsistentSubject.objects.create(subject=inconsistent_subject.subject, + redcap_url=inconsistent_subject.redcap_url) + for field in inconsistent_subject.fields: + InconsistentField.objects.create( + name=field.name, + smash_value=field.smash_value, + redcap_value=field.redcap_value, + inconsistent_subject=subject) + + def refresh_missing(self): + missing = self.find_missing() + self.add_missing(missing) + + def refresh_inconsistent(self): + missing = self.find_inconsistent() + self.add_inconsistent(missing) + def find_inconsistent(self): pid = self.get_project_id() redcap_version = self.get_redcap_version() diff --git a/smash/web/tests/test_RedcapConnector.py b/smash/web/tests/test_RedcapConnector.py index db5b57266dabca14b12fc0d2032956503661870b..61ec91793221944beada90e78420fec04f37c6b7 100644 --- a/smash/web/tests/test_RedcapConnector.py +++ b/smash/web/tests/test_RedcapConnector.py @@ -7,6 +7,8 @@ from django.test import TestCase from functions import create_subject from web.models import ConfigurationItem, Language from web.models.constants import REDCAP_TOKEN_CONFIGURATION_TYPE, REDCAP_BASE_URL_CONFIGURATION_TYPE +from web.models.inconsistent_subject import InconsistentSubject +from web.models.missing_subject import MissingSubject from web.redcap_connector import RedcapConnector, RedcapSubject from web.views.notifications import get_today_midnight_date @@ -147,3 +149,57 @@ class TestRedcapConnector(TestCase): self.assertIsNotNone(redcap_connection.get_language("xx")) self.assertIsNone(redcap_connection.get_language("yy")) + + def test_refresh_missing(self): + self.prepare_test_redcap_connection() + + redcap_connection = RedcapConnector() + redcap_connection.refresh_missing() + count = MissingSubject.objects.count() + self.assertTrue(count > 0) + + for missing in MissingSubject.objects.all(): + missing.ignore = True + missing.save() + + redcap_connection.refresh_missing() + count2 = MissingSubject.objects.count() + + self.assertEqual(count, count2) + + def test_refresh_missing_remove_old(self): + missing = MissingSubject.objects.create() + missing.ignore = False + missing.save() + self.prepare_test_redcap_connection() + + self.assertEqual(MissingSubject.objects.filter(id=missing.id).count(), 1) + + redcap_connection = RedcapConnector() + redcap_connection.refresh_missing() + self.assertTrue(MissingSubject.objects.count() > 0) + self.assertEqual(MissingSubject.objects.filter(id=missing.id).count(), 0) + + def test_refresh_missing_don_t_remove_manually_ignored(self): + missing = MissingSubject.objects.create() + missing.ignore = True + missing.save() + self.prepare_test_redcap_connection() + + self.assertEqual(MissingSubject.objects.filter(id=missing.id).count(), 1) + + redcap_connection = RedcapConnector() + redcap_connection.refresh_missing() + self.assertTrue(MissingSubject.objects.count() > 0) + self.assertEqual(MissingSubject.objects.filter(id=missing.id).count(), 1) + + def test_refresh_inconsistent_data(self): + self.prepare_test_redcap_connection() + subject = create_subject() + # noinspection SpellCheckingInspection + subject.nd_number = 'NDtest_external' + subject.save() + + redcap_connection = RedcapConnector() + redcap_connection.refresh_inconsistent() + self.assertTrue(InconsistentSubject.objects.count() > 0)