diff --git a/smash/web/api_views/subject.py b/smash/web/api_views/subject.py
index 2032b605ec28e932be7a882b665ce958279a3803..3cff62ba0a40e722aaec121f6243d10aaa0e0dd0 100644
--- a/smash/web/api_views/subject.py
+++ b/smash/web/api_views/subject.py
@@ -65,7 +65,7 @@ def get_subjects_order(subjects_to_be_ordered, order_column, order_direction):
     elif order_column == "default_location":
         result = subjects_to_be_ordered.order_by(order_direction + 'default_location')
     elif order_column == "dead":
-        result = subjects_to_be_ordered.order_by(order_direction + 'dead')
+        result = subjects_to_be_ordered.order_by(order_direction + 'subject__dead')
     elif order_column == "resigned":
         result = subjects_to_be_ordered.order_by(order_direction + 'resigned')
     elif order_column == "information_sent":
@@ -174,7 +174,7 @@ def get_subjects_filtered(subjects_to_be_filtered, filters):
         elif column == "screening_number":
             result = result.filter(screening_number__icontains=value)
         elif column == "dead":
-            result = result.filter(dead=(value == "true"))
+            result = result.filter(subject__dead=(value == "true"))
         elif column == "resigned":
             result = result.filter(resigned=(value == "true"))
         elif column == "postponed":
@@ -256,7 +256,8 @@ def subjects(request, type):
             "recordsFiltered": count_filtered,
             "data": data,
         })
-    except:
+    except Exception as e:
+        logger.error(e, exc_info=True)
         return e500_error(request)
 
 
@@ -321,7 +322,7 @@ def serialize_subject(subject):
         "nd_number": subject.nd_number,
         "screening_number": subject.screening_number,
         "default_location": location,
-        "dead": get_yes_no(subject.dead),
+        "dead": get_yes_no(subject.subject.dead),
         "resigned": get_yes_no(subject.resigned),
         "postponed": get_yes_no(subject.postponed),
         "information_sent": get_yes_no(subject.information_sent),
diff --git a/smash/web/forms.py b/smash/web/forms.py
index 6bd614c22ef7daf4da39491ea0f59b8d67be60fe..86181a51e7d32281fe4e42b18b21029265e6b563 100644
--- a/smash/web/forms.py
+++ b/smash/web/forms.py
@@ -1,11 +1,13 @@
 import datetime
+import logging
 from collections import OrderedDict
 
 from django import forms
 from django.forms import ModelForm, Form
 from django.utils.dates import MONTHS
 
-from web.models import Subject, StudySubject, Worker, Appointment, Visit, AppointmentType, ContactAttempt, AppointmentTypeLink, \
+from web.models import Subject, StudySubject, Worker, Appointment, Visit, AppointmentType, ContactAttempt, \
+    AppointmentTypeLink, \
     Availability, Holiday
 from web.models.constants import SUBJECT_TYPE_CHOICES, SCREENING_NUMBER_PREFIXES_FOR_TYPE, COUNTRY_OTHER_ID
 from web.views.notifications import get_filter_locations
@@ -35,6 +37,8 @@ TIMEPICKER_DATE_ATTRS = {
 START_YEAR_STATISTICS = 2015
 APPOINTMENT_TYPES_FIELD_POSITION = 1
 
+logger = logging.getLogger(__name__)
+
 
 def validate_subject_nd_number(self, cleaned_data):
     if cleaned_data['nd_number'] != "":
@@ -160,18 +164,13 @@ class StudySubjectEditForm(ModelForm):
                                 )
 
     def __init__(self, *args, **kwargs):
-        was_dead = kwargs.get('was_dead', False)
         was_resigned = kwargs.get('was_resigned', False)
         if 'was_resigned' in kwargs:
             kwargs.pop('was_resigned')
-        if 'was_dead' in kwargs:
-            kwargs.pop('was_dead')
         super(StudySubjectEditForm, self).__init__(*args, **kwargs)
         instance = getattr(self, 'instance', None)
         if instance and instance.id:
             self.fields['screening_number'].widget.attrs['readonly'] = True
-        if was_dead:
-            self.fields['dead'].disabled = True
         if was_resigned:
             self.fields['resigned'].disabled = True
 
@@ -187,7 +186,6 @@ class StudySubjectEditForm(ModelForm):
         exclude = ['subject']
 
 
-
 class WorkerAddForm(ModelForm):
     class Meta:
         model = Worker
@@ -548,3 +546,25 @@ class SubjectAddForm(ModelForm):
         cleaned_data = super(SubjectAddForm, self).clean()
         validate_subject_country(self, cleaned_data)
         return cleaned_data
+
+
+class SubjectEditForm(ModelForm):
+    date_born = forms.DateField(label="Date of birth",
+                                widget=forms.DateInput(DATEPICKER_DATE_ATTRS, "%Y-%m-%d"),
+                                required=False
+                                )
+
+    def __init__(self, *args, **kwargs):
+        was_dead = kwargs.get('was_dead', False)
+        if 'was_dead' in kwargs:
+            kwargs.pop('was_dead')
+        super(SubjectEditForm, self).__init__(*args, **kwargs)
+        if was_dead:
+            self.fields['dead'].disabled = True
+
+    def clean(self):
+        validate_subject_country(self, self.cleaned_data)
+
+    class Meta:
+        model = Subject
+        fields = '__all__'
diff --git a/smash/web/migrations/0068_remove_studysubject_dead.py b/smash/web/migrations/0068_remove_studysubject_dead.py
new file mode 100644
index 0000000000000000000000000000000000000000..75f6b95408308d0413cff30232afe1947145333e
--- /dev/null
+++ b/smash/web/migrations/0068_remove_studysubject_dead.py
@@ -0,0 +1,19 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.7 on 2017-11-27 15:29
+from __future__ import unicode_literals
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('web', '0067_subject'),
+    ]
+
+    operations = [
+        migrations.RemoveField(
+            model_name='studysubject',
+            name='dead',
+        ),
+    ]
diff --git a/smash/web/models/study_subject.py b/smash/web/models/study_subject.py
index 2c52d3321aa374160d946ec19673a1b1bfe8c782..46d336063d21870a5aa3779be9319e36102b626e 100644
--- a/smash/web/models/study_subject.py
+++ b/smash/web/models/study_subject.py
@@ -23,11 +23,6 @@ class StudySubject(models.Model):
             appointment.status = Appointment.APPOINTMENT_STATUS_CANCELLED
             appointment.save()
 
-    def mark_as_dead(self):
-        self.dead = True
-        self.finish_all_visits()
-        self.finish_all_appointments()
-
     def mark_as_resigned(self):
         self.resigned = True
         self.finish_all_visits()
@@ -170,11 +165,6 @@ class StudySubject(models.Model):
         verbose_name='PD in family',
         default=None,
     )
-    dead = models.BooleanField(
-        verbose_name='Deceased',
-        default=False,
-        editable=True
-    )
     resigned = models.BooleanField(
         verbose_name='Resigned',
         default=False,
diff --git a/smash/web/models/subject.py b/smash/web/models/subject.py
index ee7836ec794e80e626fa9d322b84e1db82515cd0..ae09e54185c35374522fb59b8efb790af5428c9b 100644
--- a/smash/web/models/subject.py
+++ b/smash/web/models/subject.py
@@ -2,7 +2,7 @@
 from django.db import models
 
 from constants import SEX_CHOICES, COUNTRY_OTHER_ID
-from web.models import Country
+from web.models import Country, Visit, Appointment
 from . import Language
 
 
@@ -92,6 +92,24 @@ class Subject(models.Model):
         editable=True
     )
 
+    def mark_as_dead(self):
+        self.dead = True
+        self.finish_all_visits()
+        self.finish_all_appointments()
+
+    def finish_all_visits(self):
+        visits = Visit.objects.filter(subject__subject=self, is_finished=False)
+        for visit in visits:
+            visit.is_finished = True
+            visit.save()
+
+    def finish_all_appointments(self):
+        appointments = Appointment.objects.filter(visit__subject__subject=self,
+                                                  status=Appointment.APPOINTMENT_STATUS_SCHEDULED)
+        for appointment in appointments:
+            appointment.status = Appointment.APPOINTMENT_STATUS_CANCELLED
+            appointment.save()
+
     def __str__(self):
         return "%s %s" % (self.first_name, self.last_name)
 
diff --git a/smash/web/models/visit.py b/smash/web/models/visit.py
index a1b4c9acd8aec04963df70995e16250a3aa7019d..ab3252a4b13637c0ce9535b6a44a1bebb15c1877 100644
--- a/smash/web/models/visit.py
+++ b/smash/web/models/visit.py
@@ -51,7 +51,7 @@ class Visit(models.Model):
         self.is_finished = True
         self.save()
 
-        if (not self.subject.dead) and (not self.subject.resigned):
+        if (not self.subject.subject.dead) and (not self.subject.resigned):
             visit_started = Visit.objects.filter(subject=self.subject).filter(visit_number=1)[0].datetime_begin
             follow_up_number = Visit.objects.filter(subject=self.subject).count() + 1
 
diff --git a/smash/web/redcap_connector.py b/smash/web/redcap_connector.py
index de0e9bf9bd1b26d1557dffebe3849b8d88aa6ef9..2f9b2db64a94da2d556aeacdec8010f81a988b98 100644
--- a/smash/web/redcap_connector.py
+++ b/smash/web/redcap_connector.py
@@ -189,8 +189,8 @@ class RedcapConnector(object):
         if subject_date_born != redcap_subject_date_born:
             field = InconsistentField.create("date of birth", subject_date_born, redcap_subject_date_born)
             fields.append(field)
-        if subject.dead != red_cap_subject.dead:
-            field = InconsistentField.create("dead", str(subject.dead), str(red_cap_subject.dead))
+        if subject.subject.dead != red_cap_subject.dead:
+            field = InconsistentField.create("dead", str(subject.subject.dead), str(red_cap_subject.dead))
             fields.append(field)
         if different_string(subject.mpower_id, red_cap_subject.mpower_id):
             field = InconsistentField.create("mpower id", subject.mpower_id, red_cap_subject.mpower_id)
diff --git a/smash/web/templates/subjects/edit.html b/smash/web/templates/subjects/edit.html
index 609cfbe22dab89900bfeb0343eeacf2bb54dbe3c..38e92c879ac82bec5e92986f4d92929f959553d0 100644
--- a/smash/web/templates/subjects/edit.html
+++ b/smash/web/templates/subjects/edit.html
@@ -31,7 +31,7 @@
                 back (discard changes)</a>
             </p>
             <p class="col-md-2 pull-right">
-                <a href="{% url 'web.views.subject_visit_details' subject.id %}" type="button"
+                <a href="{% url 'web.views.subject_visit_details' study_subject.id %}" type="button"
                    class="btn btn-block btn-default">Subject's visits</a>
             </p>
         </div>
@@ -48,7 +48,23 @@
                             <div class="col-md-12">
                                 {% csrf_token %}
 
-                                {% for field in form %}
+                                {% for field in study_subject_form %}
+                                    <div class="col-md-6 form-group  {% if field.errors %}has-error{% endif %}">
+                                        <label for="{# TODO #}" class="col-sm-4 control-label">
+                                            {{ field.label }}
+                                        </label>
+
+                                        <div class="col-sm-8">
+                                            {{ field|add_class:'form-control' }}
+                                        </div>
+
+                                        {% if field.errors %}
+                                            <span class="help-block"> {{ field.errors }} </span>
+                                        {% endif %}
+                                    </div>
+                                {% endfor %}
+
+                                {% for field in subject_form %}
                                     <div class="col-md-6 form-group  {% if field.errors %}has-error{% endif %}">
                                         <label for="{# TODO #}" class="col-sm-4 control-label">
                                             {{ field.label }}
@@ -88,9 +104,9 @@
             </div><!-- /.col-md-12 -->
         </div><!-- /.row -->
 
-        {% include 'includes/mail_templates_box.html' with instance_id=subject.id %}
+        {% include 'includes/mail_templates_box.html' with instance_id=study_subject.id %}
 
-        {% include 'includes/contact_attempts_box.html' with subject=subject contact_attempts=contact_attempts %}
+        {% include 'includes/contact_attempts_box.html' with subject=study_subject contact_attempts=contact_attempts %}
 
 
         <div class="modal modal-danger fade" id="confirm-dead-resigned-mark-dialog" tabindex="-1" role="dialog">
diff --git a/smash/web/tests/api_views/test_subject.py b/smash/web/tests/api_views/test_subject.py
index 576cd3540781f8313fab6fb6b91737edf4b95743..bc88318073e0f4c10eb94e76764f7efff9963f7a 100644
--- a/smash/web/tests/api_views/test_subject.py
+++ b/smash/web/tests/api_views/test_subject.py
@@ -1,22 +1,25 @@
 # coding=utf-8
-import json
 import datetime
+import json
+import logging
 
 from django.contrib.auth.models import User
 from django.test import Client
 from django.test import TestCase
 from django.urls import reverse
 
-from web.views.notifications import get_today_midnight_date
 from web.api_views.subject import get_subjects_order, get_subjects_filtered, serialize_subject, SUBJECT_LIST_GENERIC, \
     SUBJECT_LIST_NO_VISIT, SUBJECT_LIST_REQUIRE_CONTACT
-from web.models import StudySubject, Appointment, Visit
+from web.models import StudySubject, Appointment
 from web.tests.functions import create_study_subject, create_worker, create_get_suffix, create_visit, create_appointment
+from web.views.notifications import get_today_midnight_date
+
+logger = logging.getLogger(__name__)
 
 
 class TestApi(TestCase):
     def setUp(self):
-        self.subject = create_study_subject()
+        self.study_subject = create_study_subject()
         self.client = Client()
         username = 'piotr'
         password = 'top_secret'
@@ -35,8 +38,8 @@ class TestApi(TestCase):
 
         self.assertFalse(city_name in cities)
 
-        self.subject.city = city_name
-        self.subject.save()
+        self.study_subject.city = city_name
+        self.study_subject.save()
 
         response = self.client.get(reverse('web.api.cities'))
         cities = json.loads(response.content)['cities']
@@ -53,8 +56,8 @@ class TestApi(TestCase):
 
         self.assertFalse(referral_name in referrals)
 
-        self.subject.referral = referral_name
-        self.subject.save()
+        self.study_subject.referral = referral_name
+        self.study_subject.save()
 
         response = self.client.get(reverse('web.api.referrals'))
         referrals = json.loads(response.content)['referrals']
@@ -79,8 +82,8 @@ class TestApi(TestCase):
 
     def test_subjects_general_search(self):
         name = "Piotrek"
-        self.subject.first_name = name
-        self.subject.save()
+        self.study_subject.first_name = name
+        self.study_subject.save()
 
         params = {
             "columns[0][search][value]": "another_name",
@@ -116,7 +119,7 @@ class TestApi(TestCase):
             self.assertEqual(result[length - index - 1], subjects[index])
 
     def test_subjects_sort_nd_number(self):
-        subject = self.subject
+        subject = self.study_subject
         subject.nd_number = "PPP"
         subject.save()
 
@@ -127,14 +130,14 @@ class TestApi(TestCase):
         self.check_subject_ordered("nd_number", [subject, subject2])
 
     def test_subjects_sort_id(self):
-        subject = self.subject
+        subject = self.study_subject
 
         subject2 = create_study_subject(2)
 
         self.check_subject_ordered("id", [subject, subject2])
 
     def test_subjects_sort_date_born(self):
-        subject = self.subject
+        subject = self.study_subject
         subject.date_born = get_today_midnight_date()
         subject.save()
 
@@ -145,12 +148,12 @@ class TestApi(TestCase):
         self.check_subject_ordered("date_born", [subject, subject2])
 
     def test_subjects_sort_default_location(self):
-        subject = self.subject
+        subject = self.study_subject
 
         self.check_subject_ordered("default_location", [subject])
 
     def test_subjects_sort_screening_number(self):
-        subject = self.subject
+        subject = self.study_subject
         subject.screening_number = "PPP"
         subject.save()
 
@@ -161,7 +164,7 @@ class TestApi(TestCase):
         self.check_subject_ordered("screening_number", [subject, subject2])
 
     def test_subjects_sort_last_name(self):
-        subject = self.subject
+        subject = self.study_subject
         subject.last_name = "XXX"
         subject.save()
 
@@ -172,18 +175,18 @@ class TestApi(TestCase):
         self.check_subject_ordered("last_name", [subject, subject2])
 
     def test_subjects_sort_dead(self):
-        subject = self.subject
-        subject.dead = True
-        subject.save()
+        study_subject = self.study_subject
+        study_subject.subject.dead = True
+        study_subject.subject.save()
 
-        subject2 = create_study_subject(2)
-        subject2.dead = False
-        subject2.save()
+        study_subject2 = create_study_subject(2)
+        study_subject2.subject.dead = False
+        study_subject2.subject.save()
 
-        self.check_subject_ordered("dead", [subject2, subject])
+        self.check_subject_ordered("dead", [study_subject2, study_subject])
 
     def test_subjects_sort_resigned(self):
-        subject = self.subject
+        subject = self.study_subject
         subject.resigned = True
         subject.save()
 
@@ -194,7 +197,7 @@ class TestApi(TestCase):
         self.check_subject_ordered("resigned", [subject2, subject])
 
     def test_subjects_sort_postponed(self):
-        subject = self.subject
+        subject = self.study_subject
         subject.postponed = True
         subject.save()
 
@@ -205,19 +208,19 @@ class TestApi(TestCase):
         self.check_subject_ordered("postponed", [subject2, subject])
 
     def test_subjects_filter_dead(self):
-        subject = self.subject
+        subject = self.study_subject.subject
         subject.dead = True
         subject.save()
 
-        subject2 = create_study_subject(2)
-        subject2.dead = False
-        subject2.save()
+        study_subject2 = create_study_subject(2)
+        study_subject2.subject.dead = False
+        study_subject2.subject.save()
 
-        self.check_subject_filtered([["dead", "true"]], [subject])
-        self.check_subject_filtered([["dead", "false"]], [subject2])
+        self.check_subject_filtered([["dead", "true"]], [self.study_subject])
+        self.check_subject_filtered([["dead", "false"]], [study_subject2])
 
     def test_subjects_filter_nd_number(self):
-        subject = self.subject
+        subject = self.study_subject
         subject.nd_number = "PPP"
         subject.save()
 
@@ -228,7 +231,7 @@ class TestApi(TestCase):
         self.check_subject_filtered([["nd_number", "P"]], [subject])
 
     def test_subjects_filter_screening_number(self):
-        subject = self.subject
+        subject = self.study_subject
         subject.screening_number = "PPP"
         subject.save()
 
@@ -239,7 +242,7 @@ class TestApi(TestCase):
         self.check_subject_filtered([["screening_number", "Q"]], [subject2])
 
     def test_subjects_filter_last_name(self):
-        subject = self.subject
+        subject = self.study_subject
         subject.last_name = "XXX"
         subject.save()
 
@@ -250,7 +253,7 @@ class TestApi(TestCase):
         self.check_subject_filtered([["last_name", "Q"]], [])
 
     def test_subjects_filter_resigned(self):
-        subject = self.subject
+        subject = self.study_subject
         subject.resigned = True
         subject.save()
 
@@ -262,7 +265,7 @@ class TestApi(TestCase):
         self.check_subject_filtered([["resigned", "false"]], [subject2])
 
     def test_subjects_filter_postponed(self):
-        subject = self.subject
+        subject = self.study_subject
         subject.postponed = True
         subject.save()
 
@@ -274,26 +277,26 @@ class TestApi(TestCase):
         self.check_subject_filtered([["postponed", "false"]], [subject2])
 
     def test_subjects_filter_default_location(self):
-        subject = self.subject
+        subject = self.study_subject
 
         self.check_subject_filtered([["default_location", str(subject.default_location.id)]], [subject])
         self.check_subject_filtered([["default_location", "-1"]], [])
 
     def test_subjects_filter_unknown(self):
-        subject = self.subject
+        subject = self.study_subject
 
         self.check_subject_filtered([["some_unknown", "unknown data"]], [subject])
         self.check_subject_filtered([["", ""]], [subject])
 
     def test_serialize_subject(self):
-        subject = self.subject
-        subject.dead = True
+        study_subject = self.study_subject
+        study_subject.subject.dead = True
 
-        subject_json = serialize_subject(subject)
+        subject_json = serialize_subject(study_subject)
         self.assertEqual("YES", subject_json["dead"])
 
     def test_subjects_filter_visit_1_DONE(self):
-        subject = self.subject
+        subject = self.study_subject
         subject.dead = True
         subject.save()
 
@@ -313,7 +316,7 @@ class TestApi(TestCase):
         self.check_subject_filtered([["visit_1", "UPCOMING"]], [])
 
     def test_subjects_filter_visit_1_MISSED(self):
-        subject = self.subject
+        subject = self.study_subject
         subject.dead = True
         subject.save()
 
@@ -333,7 +336,7 @@ class TestApi(TestCase):
         self.check_subject_filtered([["visit_1", "UPCOMING"]], [])
 
     def test_subjects_filter_visit_1_EXCEED(self):
-        subject = self.subject
+        subject = self.study_subject
         subject.dead = True
         subject.save()
 
@@ -352,7 +355,7 @@ class TestApi(TestCase):
         self.check_subject_filtered([["visit_1", "UPCOMING"]], [])
 
     def test_subjects_filter_visit_1_IN_PROGRESS(self):
-        subject = self.subject
+        subject = self.study_subject
         subject.dead = True
         subject.save()
 
@@ -371,7 +374,7 @@ class TestApi(TestCase):
         self.check_subject_filtered([["visit_1", "UPCOMING"]], [])
 
     def test_subjects_filter_visit_1_SHOULD_BE_IN_PROGRESS(self):
-        subject = self.subject
+        subject = self.study_subject
         subject.dead = True
         subject.save()
 
@@ -387,7 +390,7 @@ class TestApi(TestCase):
         self.check_subject_filtered([["visit_1", "UPCOMING"]], [])
 
     def test_subjects_filter_visit_1_UPCOMING(self):
-        subject = self.subject
+        subject = self.study_subject
         subject.dead = True
         subject.save()
 
@@ -406,7 +409,7 @@ class TestApi(TestCase):
         self.check_subject_filtered([["visit_1", "SHOULD_BE_IN_PROGRESS"]], [])
 
     def test_subjects_filter_visit_1_visit_2_combined(self):
-        subject = self.subject
+        subject = self.study_subject
         subject.save()
 
         visit = create_visit(subject)
diff --git a/smash/web/tests/models/test_study_subject.py b/smash/web/tests/models/test_study_subject.py
new file mode 100644
index 0000000000000000000000000000000000000000..cebd56b769b72493aac87487444c0594b856bbcd
--- /dev/null
+++ b/smash/web/tests/models/test_study_subject.py
@@ -0,0 +1,21 @@
+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_visit
+
+
+class SubjectModelTests(TestCase):
+    def test_mark_as_resigned(self):
+        subject = create_study_subject()
+        visit = create_visit(subject)
+        appointment = create_appointment(visit)
+
+        subject.mark_as_resigned()
+        appointment_status = Appointment.objects.filter(id=appointment.id)[0].status
+        visit_finished = Visit.objects.filter(id=visit.id)[0].is_finished
+
+        self.assertTrue(subject.resigned)
+        self.assertTrue(visit_finished)
+        self.assertEquals(Appointment.APPOINTMENT_STATUS_CANCELLED, appointment_status)
diff --git a/smash/web/tests/models/test_subject.py b/smash/web/tests/models/test_subject.py
index 1b60733e30d2f01f3c15dcb22cfedeacbd078173..8bfdafdd9443d24be50449052c2337cb33f79997 100644
--- a/smash/web/tests/models/test_subject.py
+++ b/smash/web/tests/models/test_subject.py
@@ -1,17 +1,16 @@
-from django.contrib.auth.models import User
-from django.test import Client
 from django.test import TestCase
 
-from web.tests.functions import create_study_subject, create_appointment, create_worker
-from web.tests.functions import create_visit
 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_visit
 
 
 class SubjectModelTests(TestCase):
     def test_mark_as_dead(self):
-        subject = create_study_subject()
-        visit = create_visit(subject)
+        study_subject = create_study_subject()
+        subject = study_subject.subject
+        visit = create_visit(study_subject)
         appointment = create_appointment(visit)
 
         subject.mark_as_dead()
@@ -21,16 +20,3 @@ class SubjectModelTests(TestCase):
         self.assertTrue(subject.dead)
         self.assertTrue(visit_finished)
         self.assertEquals(Appointment.APPOINTMENT_STATUS_CANCELLED, appointment_status)
-
-    def test_mark_as_resigned(self):
-        subject = create_study_subject()
-        visit = create_visit(subject)
-        appointment = create_appointment(visit)
-
-        subject.mark_as_resigned()
-        appointment_status = Appointment.objects.filter(id=appointment.id)[0].status
-        visit_finished = Visit.objects.filter(id=visit.id)[0].is_finished
-
-        self.assertTrue(subject.resigned)
-        self.assertTrue(visit_finished)
-        self.assertEquals(Appointment.APPOINTMENT_STATUS_CANCELLED, appointment_status)
\ No newline at end of file
diff --git a/smash/web/tests/models/test_visit.py b/smash/web/tests/models/test_visit.py
index 6d5e7d8e541fe37214f61f48fdcd0346a7763bc0..b92a51bad03d90744ecbae19c14ec06c601a89ca 100644
--- a/smash/web/tests/models/test_visit.py
+++ b/smash/web/tests/models/test_visit.py
@@ -19,14 +19,14 @@ class VisitModelTests(TestCase):
         self.assertEquals(2, visit_count)
 
     def test_mark_as_finished_2(self):
-        subject = create_study_subject()
-        visit = create_visit(subject)
-        subject.dead = True
-        subject.save()
+        study_subject = create_study_subject()
+        visit = create_visit(study_subject)
+        study_subject.subject.dead = True
+        study_subject.subject.save()
 
         visit.mark_as_finished()
 
-        visit_count = Visit.objects.filter(subject=subject).count()
+        visit_count = Visit.objects.filter(subject=study_subject).count()
         self.assertEquals(1, visit_count)
 
     def test_mark_as_finished_3(self):
diff --git a/smash/web/tests/test_RedcapConnector.py b/smash/web/tests/test_RedcapConnector.py
index 3fc4c9d7cc4dc5b8bbf998e4b2becbc68e5fef94..e6faaf0dc6e92d1022d13c92b19ad4bfc627be8a 100644
--- a/smash/web/tests/test_RedcapConnector.py
+++ b/smash/web/tests/test_RedcapConnector.py
@@ -87,12 +87,12 @@ class TestRedcapConnector(TestCase):
 
     def test_create_inconsistent_data_for_dead(self):
         prepare_test_redcap_connection()
-        subject = create_study_subject()
+        study_subject = create_study_subject()
 
-        redcap_subject = self.create_redcap_subject_from_smash_subject(subject)
-        subject.dead = not subject.dead
+        redcap_subject = self.create_redcap_subject_from_smash_subject(study_subject)
+        study_subject.subject.dead = not study_subject.subject.dead
 
-        self.check_single_inconsistency(redcap_subject, subject)
+        self.check_single_inconsistency(redcap_subject, study_subject)
 
     def test_create_inconsistent_data_for_language(self):
         language = Language.objects.create(name="xx")
@@ -142,7 +142,7 @@ class TestRedcapConnector(TestCase):
         for language in subject.languages.all():
             redcap_subject.add_language(language)
         redcap_subject.mpower_id = subject.mpower_id
-        redcap_subject.dead = subject.dead
+        redcap_subject.dead = subject.subject.dead
         redcap_subject.date_born = subject.date_born
         redcap_subject.nd_number = subject.nd_number
         redcap_subject.sex = subject.sex
diff --git a/smash/web/tests/view/test_notifications.py b/smash/web/tests/view/test_notifications.py
index c4dddfab55ffbcc3b733c56d0d744d0d43849c1c..031a225c754c4a41bb50bc81a3f8fe93f1c2b3fd 100644
--- a/smash/web/tests/view/test_notifications.py
+++ b/smash/web/tests/view/test_notifications.py
@@ -225,9 +225,9 @@ class NotificationViewTests(LoggedInTestCase):
 
     def test_get_subject_with_no_visit_notifications_count_4(self):
         original_notification = get_subject_with_no_visit_notifications_count(self.user)
-        subject = create_study_subject()
-        subject.dead = True
-        subject.save()
+        study_subject = create_study_subject()
+        study_subject.subject.dead = True
+        study_subject.subject.save()
 
         notification = get_subject_with_no_visit_notifications_count(self.user)
         self.assertEquals(original_notification.count, notification.count)
diff --git a/smash/web/tests/view/test_subjects.py b/smash/web/tests/view/test_subjects.py
index a569464980e9dbf3a5059932f482c46f24f0cb9e..64bb47c568b411dd214411f0304f45a257c1ab28 100644
--- a/smash/web/tests/view/test_subjects.py
+++ b/smash/web/tests/view/test_subjects.py
@@ -1,185 +1,178 @@
 import datetime
+import logging
 
 from django.urls import reverse
 
-from web.forms import StudySubjectAddForm, StudySubjectEditForm
+from web.forms import StudySubjectAddForm, StudySubjectEditForm, SubjectEditForm, SubjectAddForm
 from web.models import StudySubject
 from web.models.constants import SEX_CHOICES_MALE, SUBJECT_TYPE_CHOICES_CONTROL, SUBJECT_TYPE_CHOICES_PATIENT, \
     COUNTRY_AFGHANISTAN_ID, COUNTRY_OTHER_ID
 from web.tests import LoggedInWithWorkerTestCase
-from web.tests.functions import create_study_subject, create_visit, create_appointment, get_test_location, \
-    create_subject
+from web.tests.functions import create_study_subject, create_visit, create_appointment, get_test_location
 from web.views.notifications import get_today_midnight_date
 
+logger = logging.getLogger(__name__)
+
 
 class SubjectsViewTests(LoggedInWithWorkerTestCase):
     def setUp(self):
         super(SubjectsViewTests, self).setUp()
-        self.subject = create_subject()
+        self.study_subject = create_study_subject()
 
-    def test_subjects_add(self):
+    def test_render_subjects_add(self):
         self.worker.save()
 
         response = self.client.get(reverse('web.views.subject_add'))
         self.assertEqual(response.status_code, 200)
 
     def test_render_subject_edit(self):
-        subject = create_study_subject()
-
-        response = self.client.get(reverse('web.views.subject_edit', kwargs={'id': subject.id}))
+        response = self.client.get(reverse('web.views.subject_edit', kwargs={'id': self.study_subject.id}))
         self.assertEqual(response.status_code, 200)
 
     def test_render_subject_visit_details(self):
-        subject = create_study_subject()
-        visit = create_visit(subject)
+        visit = create_visit(self.study_subject)
         create_appointment(visit)
 
-        response = self.client.get(reverse('web.views.subject_visit_details', kwargs={'id': subject.id}))
+        response = self.client.get(reverse('web.views.subject_visit_details', kwargs={'id': self.study_subject.id}))
         self.assertEqual(response.status_code, 200)
         self.assertFalse("Add visit" in response.content)
 
     def test_render_subject_visit_details_without_visit(self):
-        subject = create_study_subject()
-
-        response = self.client.get(reverse('web.views.subject_visit_details', kwargs={'id': subject.id}))
+        response = self.client.get(reverse('web.views.subject_visit_details', kwargs={'id': self.study_subject.id}))
         self.assertEqual(response.status_code, 200)
         self.assertTrue("Add visit" in response.content)
 
     def test_save_subject_edit_when_resigned_without_reason(self):
-        subject = create_study_subject()
-        form_subject = StudySubjectEditForm(instance=subject)
-        form_data = {}
-        for key, value in form_subject.initial.items():
-            if value is not None:
-                form_data[key] = value
+        form_data = self.create_edit_form_data_for_study_subject()
 
-        form_data['dead'] = "True"
-        form_data['resigned'] = "True"
+        form_data['subject-dead'] = "True"
+        form_data['study_subject-resigned'] = "True"
         response = self.client.post(
-            reverse('web.views.subject_edit', kwargs={'id': subject.id}), data=form_data)
+            reverse('web.views.subject_edit', kwargs={'id': self.study_subject.id}), data=form_data)
 
         self.assertEqual(response.status_code, 200)
         self.assertTrue("Resign reason cannot be empty" in response.content)
 
     def test_save_subject_edit(self):
-        subject = create_study_subject()
-        form_subject = StudySubjectEditForm(instance=subject)
-        form_data = {}
-        for key, value in form_subject.initial.items():
-            if value is not None:
-                form_data[key] = value
+        form_data = self.create_edit_form_data_for_study_subject()
 
-        form_data['dead'] = "True"
-        form_data['resigned'] = "True"
-        form_data['resign_reason'] = "doesn't want to participate"
+        form_data['subject-dead'] = "True"
+        form_data['study_subject-resigned'] = "True"
+        form_data['study_subject-resign_reason'] = "doesn't want to participate"
         response = self.client.post(
-            reverse('web.views.subject_edit', kwargs={'id': subject.id}), data=form_data)
+            reverse('web.views.subject_edit', kwargs={'id': self.study_subject.id}), data=form_data)
 
         self.assertEqual(response.status_code, 302)
-        updated_subject = StudySubject.objects.filter(id=subject.id)[0]
-        self.assertTrue(updated_subject.dead)
-        self.assertTrue(updated_subject.resigned)
+        updated_study_subject = StudySubject.objects.filter(id=self.study_subject.id)[0]
+        self.assertTrue(updated_study_subject.subject.dead)
+        self.assertTrue(updated_study_subject.resigned)
 
-    def test_subjects_add_2(self):
-
-        form = StudySubjectAddForm(user=self.user)
-        form_data = {"subject": self.subject.id}
-        for key, value in form.initial.items():
+    def create_edit_form_data_for_study_subject(self):
+        form_study_subject = StudySubjectEditForm(instance=self.study_subject, prefix="study_subject")
+        form_subject = SubjectEditForm(instance=self.study_subject.subject, prefix="subject")
+        form_data = {}
+        for key, value in form_study_subject.initial.items():
+            if value is not None:
+                form_data['study_subject-{}'.format(key)] = value
+        for key, value in form_subject.initial.items():
             if value is not None:
-                form_data[key] = value
+                form_data['subject-{}'.format(key)] = value
+        return form_data
 
+    def create_add_form_data_for_study_subject(self):
+        form_study_subject = StudySubjectAddForm(prefix="study_subject", user=self.user)
+        form_subject = SubjectAddForm(prefix="subject")
+        form_data = {}
+        for key, value in form_study_subject.initial.items():
+            if value is not None:
+                form_data['study_subject-{}'.format(key)] = value
+        for key, value in form_subject.initial.items():
+            if value is not None:
+                form_data['subject-{}'.format(key)] = value
         self.add_valid_form_data_for_subject_add(form_data)
-        form_data["type"] = SUBJECT_TYPE_CHOICES_CONTROL
-        form_data["default_location"] = get_test_location().id
+        return form_data
+
+    def test_subjects_add_2(self):
+        form_data = self.create_add_form_data_for_study_subject()
+
+        form_data["study_subject-type"] = SUBJECT_TYPE_CHOICES_CONTROL
+        form_data["study_subject-default_location"] = get_test_location().id
         response = self.client.post(reverse('web.views.subject_add'), data=form_data)
         self.assertEqual(response.status_code, 302)
         response = self.client.get(response.url)
         self.assertContains(response, "Subject created")
 
-        subject = StudySubject.objects.all()[0]
+        subject = StudySubject.objects.all().order_by("-id")[0]
         self.assertEqual("L-001", subject.screening_number,
                          "prefix should start by L" +
                          " as default location prefix is not defined and subject type is control")
 
     def add_valid_form_data_for_subject_add(self, form_data):
-        form_data["country"] = COUNTRY_AFGHANISTAN_ID
-        form_data["first_name"] = "John"
-        form_data["last_name"] = "Doe"
-        form_data["sex"] = SEX_CHOICES_MALE
-        form_data["type"] = SUBJECT_TYPE_CHOICES_PATIENT
-        form_data["subject"] = self.subject.id
+        form_data["subject-country"] = COUNTRY_AFGHANISTAN_ID
+        form_data["subject-first_name"] = "John"
+        form_data["subject-last_name"] = "Doe"
+        form_data["subject-sex"] = SEX_CHOICES_MALE
+        form_data["study_subject-type"] = SUBJECT_TYPE_CHOICES_PATIENT
+        form_data["study_subject-subject"] = self.study_subject.id
+
+        # TODO remove after refactoring
+        form_data["study_subject-country"] = COUNTRY_AFGHANISTAN_ID
+        form_data["study_subject-first_name"] = "John"
+        form_data["study_subject-last_name"] = "Doe"
+        form_data["study_subject-sex"] = SEX_CHOICES_MALE
 
     def test_subjects_add_patient(self):
+        form_data = self.create_add_form_data_for_study_subject()
 
-        form = StudySubjectAddForm(user=self.user)
-        form_data = {}
-        for key, value in form.initial.items():
-            if value is not None:
-                form_data[key] = value
-
-        self.add_valid_form_data_for_subject_add(form_data)
-        form_data["default_location"] = get_test_location().id
+        form_data["study_subject-default_location"] = get_test_location().id
         response = self.client.post(reverse('web.views.subject_add'), data=form_data)
         self.assertEqual(response.status_code, 302)
         response = self.client.get(response.url)
         self.assertContains(response, "Subject created")
 
-        subject = StudySubject.objects.all()[0]
+        subject = StudySubject.objects.all().order_by("-id")[0]
         self.assertEqual("P-001", subject.screening_number,
                          "prefix should start by P" +
                          " as default location prefix is not defined and subject type is patient")
 
     def test_subjects_add_invalid(self):
+        form_data = self.create_add_form_data_for_study_subject()
+        form_data["study_subject-type"] = SUBJECT_TYPE_CHOICES_CONTROL
+        form_data["study_subject-default_location"] = get_test_location().id
 
-        form = StudySubjectAddForm(user=self.user)
-        form_data = {}
-        for key, value in form.initial.items():
-            if value is not None:
-                form_data[key] = value
-
-        self.add_valid_form_data_for_subject_add(form_data)
-        form_data["country"] = COUNTRY_OTHER_ID
+        form_data["subject-country"] = COUNTRY_OTHER_ID
         response = self.client.post(reverse('web.views.subject_add'), data=form_data)
 
         self.assertTrue("Invalid data" in response.content)
 
     def test_subjects_add_with_prefixed_location(self):
-
-        form = StudySubjectAddForm(user=self.user)
-        form_data = {}
-        for key, value in form.initial.items():
-            if value is not None:
-                form_data[key] = value
+        form_data = self.create_add_form_data_for_study_subject()
+        form_data["study_subject-type"] = SUBJECT_TYPE_CHOICES_CONTROL
 
         self.add_valid_form_data_for_subject_add(form_data)
         location = get_test_location()
         location.prefix = 'X'
         location.save()
-        form_data["default_location"] = location.id
+        form_data["study_subject-default_location"] = get_test_location().id
         response = self.client.post(reverse('web.views.subject_add'), data=form_data)
         self.assertEqual(response.status_code, 302)
         response = self.client.get(response.url)
         self.assertContains(response, "Subject created")
 
-        subject = StudySubject.objects.all()[0]
+        subject = StudySubject.objects.all().order_by("-id")[0]
         self.assertEqual("X-001", subject.screening_number,
                          "prefix should start by X as default location prefix is equal to 'X'")
 
     def test_render_subjects(self):
-        create_study_subject()
-
         response = self.client.get(reverse('web.views.subjects'))
         self.assertEqual(response.status_code, 200)
 
     def test_render_subjects_with_no_visit(self):
-        create_study_subject()
-
         response = self.client.get(reverse('web.views.subject_no_visits'))
         self.assertEqual(response.status_code, 200)
 
     def test_render_subjects_require_contact(self):
-        subject = create_study_subject()
-        subject.datetime_contact_reminder = get_today_midnight_date() + datetime.timedelta(days=-1)
+        self.study_subject.datetime_contact_reminder = get_today_midnight_date() + datetime.timedelta(days=-1)
 
         response = self.client.get(reverse('web.views.subject_require_contact'))
         self.assertEqual(response.status_code, 200)
diff --git a/smash/web/views/notifications.py b/smash/web/views/notifications.py
index 287dc783322647d03f9fa03423aed735b92a0bab..3829d3ebebc09360004a2730fad67c52dd0df520 100644
--- a/smash/web/views/notifications.py
+++ b/smash/web/views/notifications.py
@@ -133,7 +133,7 @@ def get_notifications(the_user):
 
 def get_subjects_with_no_visit(user):
     result = StudySubject.objects.annotate(my_count=Count(Case(When(visit__is_finished=False, then=1)))).filter(
-        dead=False,
+        subject__dead=False,
         resigned=False,
         my_count=0,
         default_location__in=get_filter_locations(user),
@@ -147,7 +147,7 @@ def get_subjects_with_reminder(user):
     tomorrow = datetime.datetime.now() + datetime.timedelta(hours=1)
 
     result = StudySubject.objects.filter(
-        dead=False,
+        subject__dead=False,
         resigned=False,
         default_location__in=get_filter_locations(user),
         datetime_contact_reminder__lt=tomorrow,
diff --git a/smash/web/views/subject.py b/smash/web/views/subject.py
index d094a250cb8a5ad6cb49635ef19f3393adb5a03d..2db7e9d9588ebfd31b126db58373c9d912ad1e41 100644
--- a/smash/web/views/subject.py
+++ b/smash/web/views/subject.py
@@ -1,15 +1,19 @@
 # coding=utf-8
+import logging
+
 from django.contrib import messages
 from django.shortcuts import redirect, get_object_or_404
 
 from . import wrap_response
-from ..forms import StudySubjectAddForm, StudySubjectEditForm, VisitDetailForm
+from ..forms import StudySubjectAddForm, StudySubjectEditForm, VisitDetailForm, SubjectEditForm, SubjectAddForm
 from ..models import StudySubject, MailTemplate, Worker
 
 SUBJECT_LIST_GENERIC = "GENERIC"
 SUBJECT_LIST_NO_VISIT = "NO_VISIT"
 SUBJECT_LIST_REQUIRE_CONTACT = "REQUIRE_CONTACT"
 
+logger = logging.getLogger(__name__)
+
 
 def subjects(request):
     context = {
@@ -21,18 +25,23 @@ def subjects(request):
 
 def subject_add(request):
     if request.method == 'POST':
-        form = StudySubjectAddForm(request.POST, request.FILES, user=request.user)
-        if form.is_valid():
-            form.save()
+        study_subject_form = StudySubjectAddForm(request.POST, request.FILES, prefix="study_subject", user=request.user)
+
+        subject_form = SubjectAddForm(request.POST, request.FILES, prefix="subject")
+        if study_subject_form.is_valid() and subject_form.is_valid():
+            study_subject_form.save()
+            subject_form.save()
             messages.add_message(request, messages.SUCCESS, 'Subject created')
-            return redirect('web.views.subject_edit', id=form.instance.id)
+            return redirect('web.views.subject_edit', id=study_subject_form.instance.id)
         else:
             messages.add_message(request, messages.ERROR, 'Invalid data. Please fix data and try again.')
 
     else:
-        form = StudySubjectAddForm(user=request.user)
+        study_subject_form = StudySubjectAddForm(user=request.user, prefix="study_subject")
+        subject_form = SubjectAddForm(prefix="subject")
 
-    return wrap_response(request, 'subjects/add.html', {'form': form})
+    return wrap_response(request, 'subjects/add.html',
+                         {'study_subject_form': study_subject_form, 'subject_form': subject_form})
 
 
 def subject_no_visits(request):
@@ -50,45 +59,53 @@ def subject_require_contact(request):
 
 
 def subject_edit(request, id):
-    the_subject = get_object_or_404(StudySubject, id=id)
-    contact_attempts = the_subject.contactattempt_set.order_by('-datetime_when').all()
-    was_dead = the_subject.dead
-    was_resigned = the_subject.resigned
+    study_subject = get_object_or_404(StudySubject, id=id)
+    contact_attempts = study_subject.contactattempt_set.order_by('-datetime_when').all()
+    was_dead = study_subject.subject.dead
+    was_resigned = study_subject.resigned
     if request.method == 'POST':
-        form = StudySubjectEditForm(request.POST, request.FILES, instance=the_subject, was_dead=was_dead,
-                                    was_resigned=was_resigned)
-        if form.is_valid():
-            form.save()
+        study_subject_form = StudySubjectEditForm(request.POST, request.FILES, instance=study_subject,
+                                                  was_resigned=was_resigned, prefix="study_subject"
+                                                  )
+        subject_form = SubjectEditForm(request.POST, request.FILES, instance=study_subject.subject,
+                                       was_dead=was_dead, prefix="subject"
+                                       )
+        if study_subject_form.is_valid() and subject_form.is_valid():
+            study_subject_form.save()
+            subject_form.save()
             # check if subject was marked as dead or resigned
-            if form.cleaned_data['dead'] and not was_dead:
-                the_subject.mark_as_dead()
-            if form.cleaned_data['resigned'] and not was_resigned:
-                the_subject.mark_as_resigned()
+            if subject_form.cleaned_data['dead'] and not was_dead:
+                study_subject.subject.mark_as_dead()
+            if study_subject_form.cleaned_data['resigned'] and not was_resigned:
+                study_subject.mark_as_resigned()
             messages.success(request, "Modifications saved")
             if '_continue' in request.POST:
-                return redirect('web.views.subject_edit', id=the_subject.id)
+                return redirect('web.views.subject_edit', id=study_subject.id)
             return redirect('web.views.subjects')
         else:
             messages.add_message(request, messages.ERROR, 'Invalid data. Please fix data and try again.')
     else:
-        form = StudySubjectEditForm(instance=the_subject, was_dead=was_dead, was_resigned=was_resigned)
+        study_subject_form = StudySubjectEditForm(instance=study_subject, was_resigned=was_resigned,
+                                                  prefix="study_subject")
+        subject_form = SubjectEditForm(instance=study_subject.subject, was_dead=was_dead, prefix="subject")
 
     languages = []
-    if the_subject.default_written_communication_language:
-        languages.append(the_subject.default_written_communication_language)
-    languages.extend(the_subject.languages.all())
+    if study_subject.default_written_communication_language:
+        languages.append(study_subject.default_written_communication_language)
+    languages.extend(study_subject.languages.all())
 
     return wrap_response(request, 'subjects/edit.html', {
-        'form': form,
-        'subject': the_subject,
+        'study_subject_form': study_subject_form,
+        'subject_form': subject_form,
+        'study_subject': study_subject,
         'contact_attempts': contact_attempts,
         'mail_templates': MailTemplate.get_subject_mail_templates(languages)
     })
 
 
 def subject_visit_details(request, id):
-    subject_to_be_viewed = get_object_or_404(StudySubject, id=id)
-    visits = subject_to_be_viewed.visit_set.order_by("-visit_number").all()
+    study_subject_to_be_viewed = get_object_or_404(StudySubject, id=id)
+    visits = study_subject_to_be_viewed.visit_set.order_by("-visit_number").all()
     visits_data = []
     allow_add_visit = True
     for visit in visits: