From 19c5528508c0ebe18cb719891a52d58fad440f52 Mon Sep 17 00:00:00 2001
From: Piotr Gawron <piotr.gawron@uni.lu>
Date: Tue, 26 May 2020 08:52:19 +0200
Subject: [PATCH] iga/igg status is imported from redcap

---
 smash/db_scripts/create_dummy_data.py         |   4 +
 smash/web/api_views/subject.py                |  40 ++++++
 smash/web/forms/study_subject_forms.py        |  19 +++
 .../0171_configurationitem_serology.py        |  35 ++++++
 .../web/migrations/0172_auto_20200525_1246.py | 115 ++++++++++++++++++
 smash/web/models/constants.py                 |   2 +
 smash/web/models/study_columns.py             |  40 ++++++
 smash/web/models/study_subject.py             |  51 ++++++++
 smash/web/redcap_connector.py                 | 100 ++++++++++-----
 9 files changed, 377 insertions(+), 29 deletions(-)
 create mode 100644 smash/web/migrations/0171_configurationitem_serology.py
 create mode 100644 smash/web/migrations/0172_auto_20200525_1246.py

diff --git a/smash/db_scripts/create_dummy_data.py b/smash/db_scripts/create_dummy_data.py
index 0e44344b..c197b510 100644
--- a/smash/db_scripts/create_dummy_data.py
+++ b/smash/db_scripts/create_dummy_data.py
@@ -433,6 +433,8 @@ class smashProvider(BaseProvider):
                 default_location.prefix)
 
         virus_test_1 = choice([None, True, False], 1, p=[0.2, 0.3, 0.5])[0]
+        virus_iga_1 = choice(["Borderline", "Positive", "Negative"], 1, p=[0.02, 0.03, 0.95])[0]
+        virus_igg_1 = choice(["Borderline", "Positive", "Negative"], 1, p=[0.02, 0.03, 0.95])[0]
         if virus_test_1 is None:
             virus_test_1_updated = fake.date_between(start_date='-30d', end_date='-4d')
             #inconclusive results have a date
@@ -448,6 +450,8 @@ class smashProvider(BaseProvider):
         study_subject, _ = StudySubject.objects.update_or_create(nd_number=nd_number, subject=subject,
                                                                  virus_test_1=virus_test_1, virus_test_1_updated=virus_test_1_updated,
                                                                  virus_test_1_collection_date=virus_test_1_collection_date,
+                                                                 virus_test_1_iga_status=virus_iga_1,
+                                                                 virus_test_1_igg_status=virus_igg_1,
                                                                  defaults={'default_location': default_location, 'type': type,
                                                                            'screening_number': screening_number, 'study': study})
 
diff --git a/smash/web/api_views/subject.py b/smash/web/api_views/subject.py
index 5a8ff67a..57ed007f 100644
--- a/smash/web/api_views/subject.py
+++ b/smash/web/api_views/subject.py
@@ -105,6 +105,16 @@ def get_subject_columns(request, subject_list_type):
                    "virus_test_{}_collection_date".format(one_based_idx),
                    study_subject_columns,
                    "virus_test_date", study.columns)
+        add_column(result,
+                   "Visit {} IgA Status".format(virus_visit_number),
+                   "virus_test_{}_iga_status".format(one_based_idx),
+                   study_subject_columns,
+                   None, study.columns)
+        add_column(result,
+                   "Visit {} IgG Status".format(virus_visit_number),
+                   "virus_test_{}_igg_status".format(one_based_idx),
+                   study_subject_columns,
+                   None, study.columns)
 
     add_column(result, "Type", "type", study_subject_columns, "type_filter", study.columns)
     add_column(result, "Edit", "edit", None, None, sortable=False)
@@ -235,6 +245,26 @@ def get_subjects_order(subjects_to_be_ordered, order_column, order_direction, co
         result = subjects_to_be_ordered.order_by(order_direction + 'virus_test_4_collection_date')
     elif order_column == "virus_test_5_collection_date":
         result = subjects_to_be_ordered.order_by(order_direction + 'virus_test_5_collection_date')
+    elif order_column == "virus_test_1_iga_status":
+        result = subjects_to_be_ordered.order_by(order_direction + 'virus_test_1_iga_status')
+    elif order_column == "virus_test_1_igg_status":
+        result = subjects_to_be_ordered.order_by(order_direction + 'virus_test_1_igg_status')
+    elif order_column == "virus_test_2_iga_status":
+        result = subjects_to_be_ordered.order_by(order_direction + 'virus_test_2_iga_status')
+    elif order_column == "virus_test_2_igg_status":
+        result = subjects_to_be_ordered.order_by(order_direction + 'virus_test_2_igg_status')
+    elif order_column == "virus_test_3_iga_status":
+        result = subjects_to_be_ordered.order_by(order_direction + 'virus_test_3_iga_status')
+    elif order_column == "virus_test_3_igg_status":
+        result = subjects_to_be_ordered.order_by(order_direction + 'virus_test_3_igg_status')
+    elif order_column == "virus_test_4_iga_status":
+        result = subjects_to_be_ordered.order_by(order_direction + 'virus_test_4_iga_status')
+    elif order_column == "virus_test_4_igg_status":
+        result = subjects_to_be_ordered.order_by(order_direction + 'virus_test_4_igg_status')
+    elif order_column == "virus_test_5_iga_status":
+        result = subjects_to_be_ordered.order_by(order_direction + 'virus_test_5_iga_status')
+    elif order_column == "virus_test_5_igg_status":
+        result = subjects_to_be_ordered.order_by(order_direction + 'virus_test_5_igg_status')
     else:
         logger.warn("Unknown sort column: " + str(order_column))
     return result
@@ -549,6 +579,16 @@ def serialize_subject(study_subject):
         "virus_test_3_collection_date": study_subject.virus_test_3_collection_date,
         "virus_test_4_collection_date": study_subject.virus_test_4_collection_date,
         "virus_test_5_collection_date": study_subject.virus_test_5_collection_date,
+        "virus_test_1_iga_status": study_subject.virus_test_1_iga_status,
+        "virus_test_1_igg_status": study_subject.virus_test_1_igg_status,
+        "virus_test_2_iga_status": study_subject.virus_test_2_iga_status,
+        "virus_test_2_igg_status": study_subject.virus_test_2_igg_status,
+        "virus_test_3_iga_status": study_subject.virus_test_3_iga_status,
+        "virus_test_3_igg_status": study_subject.virus_test_3_igg_status,
+        "virus_test_4_iga_status": study_subject.virus_test_4_iga_status,
+        "virus_test_4_igg_status": study_subject.virus_test_4_igg_status,
+        "virus_test_5_iga_status": study_subject.virus_test_5_iga_status,
+        "virus_test_5_igg_status": study_subject.virus_test_5_igg_status,
         "postponed": bool_to_yes_no(study_subject.postponed),
         "brain_donation_agreement": bool_to_yes_no(study_subject.brain_donation_agreement),
         "excluded": bool_to_yes_no(study_subject.excluded),
diff --git a/smash/web/forms/study_subject_forms.py b/smash/web/forms/study_subject_forms.py
index 39f2fb0e..18fbd7aa 100644
--- a/smash/web/forms/study_subject_forms.py
+++ b/smash/web/forms/study_subject_forms.py
@@ -41,6 +41,11 @@ class StudySubjectForm(ModelForm):
                 collection_date_field = 'virus_test_{}_collection_date'.format(one_based_idx)
                 self.fields[collection_date_field].label = 'Visit {} RT-PCR collection date'.format(virus_visit_number)
 
+                iga_field = 'virus_test_{}_iga_status'.format(one_based_idx)
+                igg_field = 'virus_test_{}_igg_status'.format(one_based_idx)
+                self.fields[iga_field].label = 'Visit {} IgA status'.format(virus_visit_number)
+                self.fields[igg_field].label = 'Visit {} IgG status'.format(virus_visit_number)
+
         for visit_number in range(1, 6):
             disable_virus_test_field(self, visit_number)
             self.update_virus_inconclusive_data(visit_number)
@@ -179,10 +184,14 @@ def disable_virus_test_field(self, visit_number):
     test_result_column_name = 'virus_test_{}'.format(visit_number)
     test_result_date_column_name = 'virus_test_{}_updated'.format(visit_number)
     test_collection_date_column_name = 'virus_test_{}_collection_date'.format(visit_number)
+    test_iga_status_column_name = 'virus_test_{}_iga_status'.format(visit_number)
+    test_igg_status_column_name = 'virus_test_{}_igg_status'.format(visit_number)
     self.fields[test_result_column_name].widget.attrs['readonly'] = True
     self.fields[test_result_column_name].widget.attrs['disabled'] = True
     self.fields[test_result_date_column_name].widget.attrs['readonly'] = True
     self.fields[test_collection_date_column_name].widget.attrs['readonly'] = True
+    self.fields[test_iga_status_column_name].widget.attrs['readonly'] = True
+    self.fields[test_igg_status_column_name].widget.attrs['readonly'] = True
 
 
 def get_study_from_args(kwargs):
@@ -241,6 +250,16 @@ def prepare_study_subject_fields(fields, study):
     prepare_field(fields, study.columns, 'virus_test_3_collection_date')
     prepare_field(fields, study.columns, 'virus_test_4_collection_date')
     prepare_field(fields, study.columns, 'virus_test_5_collection_date')
+    prepare_field(fields, study.columns, 'virus_test_1_iga_status')
+    prepare_field(fields, study.columns, 'virus_test_1_igg_status')
+    prepare_field(fields, study.columns, 'virus_test_2_iga_status')
+    prepare_field(fields, study.columns, 'virus_test_2_igg_status')
+    prepare_field(fields, study.columns, 'virus_test_3_iga_status')
+    prepare_field(fields, study.columns, 'virus_test_3_igg_status')
+    prepare_field(fields, study.columns, 'virus_test_4_iga_status')
+    prepare_field(fields, study.columns, 'virus_test_4_igg_status')
+    prepare_field(fields, study.columns, 'virus_test_5_iga_status')
+    prepare_field(fields, study.columns, 'virus_test_5_igg_status')
 
 
 def validate_subject_screening_number(self, cleaned_data):
diff --git a/smash/web/migrations/0171_configurationitem_serology.py b/smash/web/migrations/0171_configurationitem_serology.py
new file mode 100644
index 00000000..824e5381
--- /dev/null
+++ b/smash/web/migrations/0171_configurationitem_serology.py
@@ -0,0 +1,35 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.3 on 2017-04-04 09:43
+from __future__ import unicode_literals
+
+from django.db import migrations
+
+from web.models.constants import RED_CAP_IGA_STATUS_FIELD_TYPE, RED_CAP_IGG_STATUS_FIELD_TYPE
+
+
+def create_item(apps, type, value, name):
+    # We can't import the ConfigurationItem model directly as it may be a newer
+    # version than this migration expects. We use the historical version.
+    ConfigurationItem = apps.get_model("web", "ConfigurationItem")
+    item = ConfigurationItem.objects.create()
+    item.type = type
+    item.value = value
+    item.name = name
+    item.save()
+
+
+def configuration_items(apps, schema_editor):
+    create_item(apps, RED_CAP_IGA_STATUS_FIELD_TYPE, "",
+                "Redcap field for IgA status in the visit")
+    create_item(apps, RED_CAP_IGG_STATUS_FIELD_TYPE, "",
+                "Redcap field for IgG status in the visit")
+
+
+class Migration(migrations.Migration):
+    dependencies = [
+        ('web', '0170_auto_20200525_1126'),
+    ]
+
+    operations = [
+        migrations.RunPython(configuration_items),
+    ]
diff --git a/smash/web/migrations/0172_auto_20200525_1246.py b/smash/web/migrations/0172_auto_20200525_1246.py
new file mode 100644
index 00000000..0750d0a9
--- /dev/null
+++ b/smash/web/migrations/0172_auto_20200525_1246.py
@@ -0,0 +1,115 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.5 on 2020-05-25 12:46
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('web', '0171_configurationitem_serology'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='studycolumns',
+            name='virus_test_1_iga_status',
+            field=models.BooleanField(default=False, verbose_name=b'Visit 1 virus IgA status'),
+        ),
+        migrations.AddField(
+            model_name='studycolumns',
+            name='virus_test_1_igg_status',
+            field=models.BooleanField(default=False, verbose_name=b'Visit 1 virus IgG status'),
+        ),
+        migrations.AddField(
+            model_name='studycolumns',
+            name='virus_test_2_iga_status',
+            field=models.BooleanField(default=False, verbose_name=b'Visit 2 virus IgA status'),
+        ),
+        migrations.AddField(
+            model_name='studycolumns',
+            name='virus_test_2_igg_status',
+            field=models.BooleanField(default=False, verbose_name=b'Visit 2 virus IgG status'),
+        ),
+        migrations.AddField(
+            model_name='studycolumns',
+            name='virus_test_3_iga_status',
+            field=models.BooleanField(default=False, verbose_name=b'Visit 3 virus IgA status'),
+        ),
+        migrations.AddField(
+            model_name='studycolumns',
+            name='virus_test_3_igg_status',
+            field=models.BooleanField(default=False, verbose_name=b'Visit 3 virus IgG status'),
+        ),
+        migrations.AddField(
+            model_name='studycolumns',
+            name='virus_test_4_iga_status',
+            field=models.BooleanField(default=False, verbose_name=b'Visit 4 virus IgA status'),
+        ),
+        migrations.AddField(
+            model_name='studycolumns',
+            name='virus_test_4_igg_status',
+            field=models.BooleanField(default=False, verbose_name=b'Visit 4 virus IgG status'),
+        ),
+        migrations.AddField(
+            model_name='studycolumns',
+            name='virus_test_5_iga_status',
+            field=models.BooleanField(default=False, verbose_name=b'Visit 5 virus IgA status'),
+        ),
+        migrations.AddField(
+            model_name='studycolumns',
+            name='virus_test_5_igg_status',
+            field=models.BooleanField(default=False, verbose_name=b'Visit 5 virus IgG status'),
+        ),
+        migrations.AddField(
+            model_name='studysubject',
+            name='virus_test_1_iga_status',
+            field=models.CharField(blank=True, max_length=255, null=True, verbose_name=b'Visit 1 IgA status'),
+        ),
+        migrations.AddField(
+            model_name='studysubject',
+            name='virus_test_1_igg_status',
+            field=models.CharField(blank=True, max_length=255, null=True, verbose_name=b'Visit 1 IgG status'),
+        ),
+        migrations.AddField(
+            model_name='studysubject',
+            name='virus_test_2_iga_status',
+            field=models.CharField(blank=True, max_length=255, null=True, verbose_name=b'Visit 2 IgA status'),
+        ),
+        migrations.AddField(
+            model_name='studysubject',
+            name='virus_test_2_igg_status',
+            field=models.CharField(blank=True, max_length=255, null=True, verbose_name=b'Visit 2 IgG status'),
+        ),
+        migrations.AddField(
+            model_name='studysubject',
+            name='virus_test_3_iga_status',
+            field=models.CharField(blank=True, max_length=255, null=True, verbose_name=b'Visit 3 IgA status'),
+        ),
+        migrations.AddField(
+            model_name='studysubject',
+            name='virus_test_3_igg_status',
+            field=models.CharField(blank=True, max_length=255, null=True, verbose_name=b'Visit 3 IgG status'),
+        ),
+        migrations.AddField(
+            model_name='studysubject',
+            name='virus_test_4_iga_status',
+            field=models.CharField(blank=True, max_length=255, null=True, verbose_name=b'Visit 4 IgA status'),
+        ),
+        migrations.AddField(
+            model_name='studysubject',
+            name='virus_test_4_igg_status',
+            field=models.CharField(blank=True, max_length=255, null=True, verbose_name=b'Visit 4 IgG status'),
+        ),
+        migrations.AddField(
+            model_name='studysubject',
+            name='virus_test_5_iga_status',
+            field=models.CharField(blank=True, max_length=255, null=True, verbose_name=b'Visit 5 IgA status'),
+        ),
+        migrations.AddField(
+            model_name='studysubject',
+            name='virus_test_5_igg_status',
+            field=models.CharField(blank=True, max_length=255, null=True, verbose_name=b'Visit 5 IgG status'),
+        ),
+    ]
diff --git a/smash/web/models/constants.py b/smash/web/models/constants.py
index 498c9a6a..529d54fd 100644
--- a/smash/web/models/constants.py
+++ b/smash/web/models/constants.py
@@ -67,6 +67,8 @@ RED_CAP_ND_NUMBER_FIELD_TYPE = 'RED_CAP_ND_NUMBER_FIELD_TYPE'
 RED_CAP_VIRUS_FIELD_TYPE = 'RED_CAP_VIRUS_FIELD_TYPE'
 RED_CAP_KIT_ID_FIELD_TYPE = "RED_CAP_KIT_ID_FIELD_TYPE"
 RED_CAP_SAMPLE_DATE_FIELD_TYPE = "RED_CAP_SAMPLE_DATE_FIELD_TYPE"
+RED_CAP_IGA_STATUS_FIELD_TYPE = "RED_CAP_IGA_STATUS_FIELD_TYPE"
+RED_CAP_IGG_STATUS_FIELD_TYPE = "RED_CAP_IGG_STATUS_FIELD_TYPE"
 
 
 MAIL_TEMPLATE_CONTEXT_SUBJECT = 'S'
diff --git a/smash/web/models/study_columns.py b/smash/web/models/study_columns.py
index ac3954fa..858db85a 100644
--- a/smash/web/models/study_columns.py
+++ b/smash/web/models/study_columns.py
@@ -182,3 +182,43 @@ class StudyColumns(models.Model):
         default=False,
         verbose_name='Visit 5 virus collection date',
     )
+    virus_test_1_iga_status = models.BooleanField(
+        default=False,
+        verbose_name='Visit 1 virus IgA status',
+    )
+    virus_test_1_igg_status = models.BooleanField(
+        default=False,
+        verbose_name='Visit 1 virus IgG status',
+    )
+    virus_test_2_iga_status = models.BooleanField(
+        default=False,
+        verbose_name='Visit 2 virus IgA status',
+    )
+    virus_test_2_igg_status = models.BooleanField(
+        default=False,
+        verbose_name='Visit 2 virus IgG status',
+    )
+    virus_test_3_iga_status = models.BooleanField(
+        default=False,
+        verbose_name='Visit 3 virus IgA status',
+    )
+    virus_test_3_igg_status = models.BooleanField(
+        default=False,
+        verbose_name='Visit 3 virus IgG status',
+    )
+    virus_test_4_iga_status = models.BooleanField(
+        default=False,
+        verbose_name='Visit 4 virus IgA status',
+    )
+    virus_test_4_igg_status = models.BooleanField(
+        default=False,
+        verbose_name='Visit 4 virus IgG status',
+    )
+    virus_test_5_iga_status = models.BooleanField(
+        default=False,
+        verbose_name='Visit 5 virus IgA status',
+    )
+    virus_test_5_igg_status = models.BooleanField(
+        default=False,
+        verbose_name='Visit 5 virus IgG status',
+    )
diff --git a/smash/web/models/study_subject.py b/smash/web/models/study_subject.py
index 99a0ebb8..a92c4c2c 100644
--- a/smash/web/models/study_subject.py
+++ b/smash/web/models/study_subject.py
@@ -263,6 +263,57 @@ class StudySubject(models.Model):
                                                     null=True,
                                                     )
 
+    virus_test_1_iga_status = models.CharField(max_length=255,
+                                               verbose_name='Visit 1 IgA status',
+                                               blank=True,
+                                               null=True,
+                                               )
+    virus_test_1_igg_status = models.CharField(max_length=255,
+                                               verbose_name='Visit 1 IgG status',
+                                               blank=True,
+                                               null=True,
+                                               )
+    virus_test_2_iga_status = models.CharField(max_length=255,
+                                               verbose_name='Visit 2 IgA status',
+                                               blank=True,
+                                               null=True,
+                                               )
+    virus_test_2_igg_status = models.CharField(max_length=255,
+                                               verbose_name='Visit 2 IgG status',
+                                               blank=True,
+                                               null=True,
+                                               )
+    virus_test_3_iga_status = models.CharField(max_length=255,
+                                               verbose_name='Visit 3 IgA status',
+                                               blank=True,
+                                               null=True,
+                                               )
+    virus_test_3_igg_status = models.CharField(max_length=255,
+                                               verbose_name='Visit 3 IgG status',
+                                               blank=True,
+                                               null=True,
+                                               )
+    virus_test_4_iga_status = models.CharField(max_length=255,
+                                               verbose_name='Visit 4 IgA status',
+                                               blank=True,
+                                               null=True,
+                                               )
+    virus_test_4_igg_status = models.CharField(max_length=255,
+                                               verbose_name='Visit 4 IgG status',
+                                               blank=True,
+                                               null=True,
+                                               )
+    virus_test_5_iga_status = models.CharField(max_length=255,
+                                               verbose_name='Visit 5 IgA status',
+                                               blank=True,
+                                               null=True,
+                                               )
+    virus_test_5_igg_status = models.CharField(max_length=255,
+                                               verbose_name='Visit 5 IgG status',
+                                               blank=True,
+                                               null=True,
+                                               )
+
     def sort_matched_screening_first(self, pattern, reverse=False):
         if self.screening_number is None:
             return None
diff --git a/smash/web/redcap_connector.py b/smash/web/redcap_connector.py
index 0bd62843..9e699cf9 100644
--- a/smash/web/redcap_connector.py
+++ b/smash/web/redcap_connector.py
@@ -17,7 +17,8 @@ from web.models.constants import REDCAP_TOKEN_CONFIGURATION_TYPE, \
     REDCAP_BASE_URL_CONFIGURATION_TYPE, CRON_JOB_TIMEOUT, RED_CAP_LANGUAGE_4_FIELD_TYPE, RED_CAP_LANGUAGE_3_FIELD_TYPE, \
     RED_CAP_LANGUAGE_2_FIELD_TYPE, RED_CAP_LANGUAGE_1_FIELD_TYPE, RED_CAP_MPOWER_ID_FIELD_TYPE, RED_CAP_DEAD_FIELD_TYPE, \
     RED_CAP_SEX_FIELD_TYPE, RED_CAP_DATE_BORN_FIELD_TYPE, RED_CAP_ND_NUMBER_FIELD_TYPE, RED_CAP_VIRUS_FIELD_TYPE, \
-    GLOBAL_STUDY_ID, RED_CAP_SAMPLE_DATE_FIELD_TYPE, RED_CAP_KIT_ID_FIELD_TYPE
+    GLOBAL_STUDY_ID, RED_CAP_SAMPLE_DATE_FIELD_TYPE, RED_CAP_KIT_ID_FIELD_TYPE, RED_CAP_IGA_STATUS_FIELD_TYPE, \
+    RED_CAP_IGG_STATUS_FIELD_TYPE
 from web.models.inconsistent_subject import InconsistentField, InconsistentSubject
 from web.models.missing_subject import MissingSubject
 
@@ -47,6 +48,8 @@ class RedcapVisit(object):
     virus_inconclusive = False
     visit_number = 0
     virus_collection_date = None
+    iga_status = None
+    igg_status = None
 
 
 def different_string(string1, string2):
@@ -94,6 +97,8 @@ class RedcapConnector(object):
         self.virus_field = ConfigurationItem.objects.get(type=RED_CAP_VIRUS_FIELD_TYPE).value
         self.sample_kit_id_field = ConfigurationItem.objects.get(type=RED_CAP_KIT_ID_FIELD_TYPE).value
         self.sample_date_field = ConfigurationItem.objects.get(type=RED_CAP_SAMPLE_DATE_FIELD_TYPE).value
+        self.iga_status_field = ConfigurationItem.objects.get(type=RED_CAP_IGA_STATUS_FIELD_TYPE).value
+        self.igg_status_field = ConfigurationItem.objects.get(type=RED_CAP_IGG_STATUS_FIELD_TYPE).value
 
         self.study = Study.objects.get(id=GLOBAL_STUDY_ID)
 
@@ -230,46 +235,72 @@ class RedcapConnector(object):
                                 smasch_appointment.visit.is_finished = True
                                 smasch_appointment.visit.save()
                         if visit.virus is not None or visit.virus_inconclusive:
-                            changes = None
+                            changes = []
                             if visit.visit_number == 1 and subject.virus_test_1 != visit.virus:
-                                changes = [('virus_test_1', visit.virus),
-                                           ('virus_test_1_updated', datetime.datetime.now())]
+                                changes.extend([('virus_test_1', visit.virus),
+                                                ('virus_test_1_updated', datetime.datetime.now())])
                             if visit.visit_number == 2 and subject.virus_test_2 != visit.virus:
-                                changes = [('virus_test_2', visit.virus),
-                                           ('virus_test_2_updated', datetime.datetime.now())]
+                                changes.extend([('virus_test_2', visit.virus),
+                                                ('virus_test_2_updated', datetime.datetime.now())])
                             if visit.visit_number == 3 and subject.virus_test_3 != visit.virus:
-                                changes = [('virus_test_3', visit.virus),
-                                           ('virus_test_3_updated', datetime.datetime.now())]
+                                changes.extend([('virus_test_3', visit.virus),
+                                                ('virus_test_3_updated', datetime.datetime.now())])
                             if visit.visit_number == 4 and subject.virus_test_4 != visit.virus:
-                                changes = [('virus_test_4', visit.virus),
-                                           ('virus_test_4_updated', datetime.datetime.now())]
+                                changes.extend([('virus_test_4', visit.virus),
+                                                ('virus_test_4_updated', datetime.datetime.now())])
                             if visit.visit_number == 5 and subject.virus_test_5 != visit.virus:
-                                changes = [('virus_test_5', visit.virus),
-                                           ('virus_test_5_updated', datetime.datetime.now())]
+                                changes.extend([('virus_test_5', visit.virus),
+                                                ('virus_test_5_updated', datetime.datetime.now())])
                             if visit.visit_number == 1 and subject.virus_test_1_updated is None and visit.virus_inconclusive:
-                                changes = [('virus_test_1_updated', datetime.datetime.now())]
+                                changes.extend([('virus_test_1_updated', datetime.datetime.now())])
                             if visit.visit_number == 2 and subject.virus_test_2_updated is None and visit.virus_inconclusive:
-                                changes = [('virus_test_2_updated', datetime.datetime.now())]
+                                changes.extend([('virus_test_2_updated', datetime.datetime.now())])
                             if visit.visit_number == 3 and subject.virus_test_3_updated is None and visit.virus_inconclusive:
-                                changes = [('virus_test_3_updated', datetime.datetime.now())]
+                                changes.extend([('virus_test_3_updated', datetime.datetime.now())])
                             if visit.visit_number == 4 and subject.virus_test_4_updated is None and visit.virus_inconclusive:
-                                changes = [('virus_test_4_updated', datetime.datetime.now())]
+                                changes.extend([('virus_test_4_updated', datetime.datetime.now())])
                             if visit.visit_number == 5 and subject.virus_test_5_updated is None and visit.virus_inconclusive:
-                                changes = [('virus_test_5_updated', datetime.datetime.now())]
-
-                            if visit.visit_number == 1 and not date_equals(subject.virus_test_1_collection_date , visit.virus_collection_date):
-                                changes = [('virus_test_1_collection_date', visit.virus_collection_date)]
-                            if visit.visit_number == 2 and subject.virus_test_2_collection_date != visit.virus_collection_date:
-                                changes = [('virus_test_2_collection_date', visit.virus_collection_date)]
-                            if visit.visit_number == 3 and subject.virus_test_3_collection_date != visit.virus_collection_date:
-                                changes = [('virus_test_3_collection_date', visit.virus_collection_date)]
-                            if visit.visit_number == 4 and subject.virus_test_4_collection_date != visit.virus_collection_date:
-                                changes = [('virus_test_4_collection_date', visit.virus_collection_date)]
-                            if visit.visit_number == 5 and subject.virus_test_5_collection_date != visit.virus_collection_date:
-                                changes = [('virus_test_5_collection_date', visit.virus_collection_date)]
+                                changes.extend([('virus_test_5_updated', datetime.datetime.now())])
+
+                            if visit.visit_number == 1 and not date_equals(subject.virus_test_1_collection_date,
+                                                                           visit.virus_collection_date):
+                                changes.extend([('virus_test_1_collection_date', visit.virus_collection_date)])
+                            if visit.visit_number == 2 and not date_equals(subject.virus_test_2_collection_date,
+                                                                       visit.virus_collection_date):
+                                changes.extend([('virus_test_2_collection_date', visit.virus_collection_date)])
+                            if visit.visit_number == 3 and not date_equals(subject.virus_test_3_collection_date,
+                                                                       visit.virus_collection_date):
+                                changes.extend([('virus_test_3_collection_date', visit.virus_collection_date)])
+                            if visit.visit_number == 4 and not date_equals(subject.virus_test_4_collection_date,
+                                                                       visit.virus_collection_date):
+                                changes.extend([('virus_test_4_collection_date', visit.virus_collection_date)])
+                            if visit.visit_number == 5 and not date_equals(subject.virus_test_5_collection_date,
+                                                                       visit.virus_collection_date):
+                                changes.extend([('virus_test_5_collection_date', visit.virus_collection_date)])
+
+                            if visit.visit_number == 1 and subject.virus_test_1_iga_status != visit.iga_status:
+                                changes.extend([('virus_test_1_iga_status', visit.iga_status)])
+                            if visit.visit_number == 1 and subject.virus_test_1_igg_status != visit.igg_status:
+                                changes.extend([('virus_test_1_igg_status', visit.igg_status)])
+                            if visit.visit_number == 2 and subject.virus_test_2_iga_status != visit.iga_status:
+                                changes.extend([('virus_test_2_iga_status', visit.iga_status)])
+                            if visit.visit_number == 2 and subject.virus_test_2_igg_status != visit.igg_status:
+                                changes.extend([('virus_test_2_igg_status', visit.igg_status)])
+                            if visit.visit_number == 3 and subject.virus_test_3_iga_status != visit.iga_status:
+                                changes.extend([('virus_test_3_iga_status', visit.iga_status)])
+                            if visit.visit_number == 3 and subject.virus_test_3_igg_status != visit.igg_status:
+                                changes.extend([('virus_test_3_igg_status', visit.igg_status)])
+                            if visit.visit_number == 4 and subject.virus_test_4_iga_status != visit.iga_status:
+                                changes.extend([('virus_test_4_iga_status', visit.iga_status)])
+                            if visit.visit_number == 4 and subject.virus_test_4_igg_status != visit.igg_status:
+                                changes.extend([('virus_test_4_igg_status', visit.igg_status)])
+                            if visit.visit_number == 5 and subject.virus_test_5_iga_status != visit.iga_status:
+                                changes.extend([('virus_test_5_iga_status', visit.iga_status)])
+                            if visit.visit_number == 5 and subject.virus_test_5_igg_status != visit.igg_status:
+                                changes.extend([('virus_test_5_igg_status', visit.igg_status)])
 
                             #
-                            if changes is not None:
+                            if len(changes) > 0:
                                 for field, new_value in changes:
                                     old_value = getattr(subject, field)
                                     description = u'{} changed from "{}" to "{}"'.format(field, old_value, new_value)
@@ -407,6 +438,11 @@ class RedcapConnector(object):
                             logger.warn("Invalid date: " + row.get(self.sample_date_field))
                             visit.virus_collection_date = None
 
+                if self.iga_status_field != "":
+                    visit.iga_status = row.get(self.iga_status_field)
+                if self.igg_status_field != "":
+                    visit.igg_status = row.get(self.igg_status_field)
+
                 if self.sample_kit_id_field != "":
                     if row.get(self.sample_kit_id_field) != "":
                         redcap_subject.visits.append(visit)
@@ -486,6 +522,12 @@ class RedcapConnector(object):
         if self.sample_date_field != "":
             result['fields[' + str(field_number) + ']'] = self.sample_date_field
             field_number += 1
+        if self.iga_status_field != "":
+            result['fields[' + str(field_number) + ']'] = self.iga_status_field
+            field_number += 1
+        if self.igg_status_field != "":
+            result['fields[' + str(field_number) + ']'] = self.igg_status_field
+            field_number += 1
         return result
 
     def get_language(self, name):
-- 
GitLab