diff --git a/smash/web/api_views/daily_planning.py b/smash/web/api_views/daily_planning.py
index cca2057d53c58f1e41114d90968e1026ac759a51..ad3c0a94387f1c64266194de086ae60a805bb9c5 100644
--- a/smash/web/api_views/daily_planning.py
+++ b/smash/web/api_views/daily_planning.py
@@ -8,6 +8,7 @@ from django.http import JsonResponse
 from django.shortcuts import get_object_or_404
 
 from web.models import Appointment, AppointmentTypeLink, Worker, Availability, Holiday
+from web.models.worker_study_role import WORKER_STAFF
 from web.views import e500_error
 from web.views.notifications import get_filter_locations
 
@@ -300,9 +301,9 @@ def events(request, date):
 
 
 def get_workers_for_daily_planning(request):
-    result = Worker.objects.filter(locations__in=get_filter_locations(request.user)). \
-        filter(user__is_active=True).exclude(
-        role=Worker.ROLE_CHOICES_SECRETARY).distinct()
+    result = Worker.get_workers_by_worker_type(WORKER_STAFF).filter(
+        locations__in=get_filter_locations(request.user)).filter(
+        user__is_active=True).distinct()
     return result
 
 
diff --git a/smash/web/api_views/worker.py b/smash/web/api_views/worker.py
index d9edbcc1dab1a455c7c29f53165b8b278d86802a..e3ca26040d94afab46ef7be02094923a841258ee 100644
--- a/smash/web/api_views/worker.py
+++ b/smash/web/api_views/worker.py
@@ -4,6 +4,7 @@ from django.contrib.auth.decorators import login_required
 from django.http import JsonResponse
 from django.utils import timezone
 
+from web.models.constants import GLOBAL_STUDY_ID
 from web.api_views.daily_planning import get_workers_for_daily_planning, get_availabilities
 from ..models import Worker
 
@@ -29,10 +30,11 @@ def workers_for_daily_planning(request):
     workers = get_workers_for_daily_planning(request)
     workers_list_for_json = []
     for worker in workers:
+        role = unicode(worker.roles.filter(study_id=GLOBAL_STUDY_ID)[0].role)
         worker_dict_for_json = {
             'id': worker.id,
-            'title': u"{} ({})".format(unicode(worker), worker.get_role_display()[:1].upper()),
-            'role': worker.get_role_display()
+            'title': u"{} ({})".format(unicode(worker), role[:1].upper()),
+            'role': role
         }
         workers_list_for_json.append(worker_dict_for_json)
     return JsonResponse(workers_list_for_json, safe=False)
diff --git a/smash/web/forms/__init__.py b/smash/web/forms/__init__.py
index 23d44c9490bb74edddc5ec5ad5d436dffd829ae2..99186b1cc4900b521e0d35da9727beff58ee5c20 100644
--- a/smash/web/forms/__init__.py
+++ b/smash/web/forms/__init__.py
@@ -1,13 +1,15 @@
-from forms import WorkerAddForm, \
-    WorkerEditForm, AppointmentDetailForm, AppointmentEditForm, AppointmentAddForm, VisitDetailForm, VisitAddForm, \
-    ContactAttemptForm, ContactAttemptEditForm, KitRequestForm, StatisticsForm, AvailabilityAddForm, \
+from worker_form import WorkerForm
+from forms import VisitDetailForm, \
+    VisitAddForm, KitRequestForm, StatisticsForm, AvailabilityAddForm, \
     AvailabilityEditForm, HolidayAddForm
+from contact_attempt_forms import ContactAttemptAddForm, ContactAttemptEditForm
+from appointment_form import AppointmentDetailForm, AppointmentEditForm, AppointmentAddForm
 from study_subject_forms import StudySubjectAddForm, StudySubjectDetailForm, StudySubjectEditForm
 from subject_forms import SubjectAddForm, SubjectEditForm, SubjectDetailForm
 from voucher_forms import VoucherTypeForm, VoucherTypePriceForm, VoucherForm
 
-__all__ = [StudySubjectAddForm, StudySubjectDetailForm, StudySubjectEditForm, WorkerAddForm, WorkerEditForm,
+__all__ = [StudySubjectAddForm, StudySubjectDetailForm, StudySubjectEditForm, WorkerForm,
            AppointmentDetailForm, AppointmentEditForm, AppointmentAddForm, VisitDetailForm, VisitAddForm,
-           ContactAttemptForm, ContactAttemptEditForm, KitRequestForm, StatisticsForm, AvailabilityAddForm,
+           ContactAttemptAddForm, ContactAttemptEditForm, KitRequestForm, StatisticsForm, AvailabilityAddForm,
            AvailabilityEditForm, HolidayAddForm, SubjectAddForm, SubjectEditForm, SubjectDetailForm, VoucherTypeForm,
            VoucherTypePriceForm, VoucherForm]
diff --git a/smash/web/forms/appointment_form.py b/smash/web/forms/appointment_form.py
new file mode 100644
index 0000000000000000000000000000000000000000..83b40597bc5d3ad21a7b5927e5a5c73e59004ff1
--- /dev/null
+++ b/smash/web/forms/appointment_form.py
@@ -0,0 +1,134 @@
+import logging
+from collections import OrderedDict
+
+from django import forms
+from django.forms import ModelForm
+
+from web.models.worker_study_role import WORKER_STAFF
+from web.forms.forms import DATETIMEPICKER_DATE_ATTRS, APPOINTMENT_TYPES_FIELD_POSITION
+from web.models import Appointment, Worker, AppointmentTypeLink, AppointmentType
+from web.views.notifications import get_filter_locations
+
+logger = logging.getLogger(__name__)
+
+
+class AppointmentForm(ModelForm):
+    datetime_when = forms.DateTimeField(label='Appointment on',
+                                        widget=forms.DateTimeInput(DATETIMEPICKER_DATE_ATTRS)
+                                        )
+
+    def __init__(self, *args, **kwargs):
+        super(AppointmentForm, self).__init__(*args, **kwargs)
+        self.fields['worker_assigned'].queryset = Worker.get_workers_by_worker_type(WORKER_STAFF).filter(
+            locations__in=get_filter_locations(self.user)).distinct().order_by('first_name', 'last_name')
+
+
+class AppointmentDetailForm(AppointmentForm):
+    class Meta:
+        model = Appointment
+        fields = '__all__'
+
+
+class AppointmentEditForm(AppointmentForm):
+    class Meta:
+        model = Appointment
+        fields = '__all__'
+        exclude = ['appointment_types']
+
+    def __init__(self, *args, **kwargs):
+        user = kwargs.pop('user', None)
+        if user is None:
+            raise TypeError("User not defined")
+        self.user = Worker.get_by_user(user)
+        if self.user is None:
+            raise TypeError("Worker not defined for: " + user.username)
+        super(AppointmentEditForm, self).__init__(*args, **kwargs)
+        if 'instance' in kwargs:
+            initial_appointment_types = AppointmentTypeLink.objects.filter(appointment=kwargs['instance']).values_list(
+                'appointment_type', flat=True)
+        else:
+            initial_appointment_types = []
+        fields = OrderedDict()
+        for i, tuple in enumerate(self.fields.items()):
+            key, value = tuple
+            fields[key] = value
+            if i == APPOINTMENT_TYPES_FIELD_POSITION:
+                fields['appointment_types'] = forms.ModelMultipleChoiceField(required=False,
+                                                                             widget=forms.CheckboxSelectMultiple,
+                                                                             queryset=AppointmentType.objects.all(),
+                                                                             initial=initial_appointment_types)
+        self.fields = fields
+        self.fields['location'].queryset = get_filter_locations(self.user)
+
+    def clean_location(self):
+        location = self.cleaned_data['location']
+        if self.user.locations.filter(id=location.id).count() == 0:
+            self.add_error('location', "You cannot create appointment for this location")
+        else:
+            return location
+
+    def save(self, commit=True):
+        appointment = super(AppointmentEditForm, self).save(commit)
+        # if appointment date change, remove appointment_type links
+        if 'datetime_when' in self.changed_data:
+            AppointmentTypeLink.objects.filter(appointment=appointment).delete()
+            appointment_type_links = []
+        else:
+            appointment_type_links = AppointmentTypeLink.objects.filter(appointment=appointment).all()
+        appointment_types_from_links = []
+        appointment_types = self.cleaned_data['appointment_types']
+        for appointment_type_link in appointment_type_links:
+            if appointment_type_link.appointment_type not in appointment_types:
+                # we delete appointment links for appointments types that have been removed
+                appointment_type_link.delete()
+            else:
+                appointment_types_from_links.append(appointment_type_link.appointment_type)
+        for appointment_type in appointment_types:
+            if appointment_type not in appointment_types_from_links:
+                # we create new appointment links for appointments types that have been added
+                appointment_type_link = AppointmentTypeLink(appointment=appointment,
+                                                            appointment_type=appointment_type)
+                appointment_type_link.save()
+        return appointment
+
+
+class AppointmentAddForm(AppointmentForm):
+    class Meta:
+        model = Appointment
+        exclude = ['status', 'appointment_types']
+
+    def __init__(self, *args, **kwargs):
+        user = kwargs.pop('user', None)
+        if user is None:
+            raise TypeError("User not defined")
+        self.user = Worker.get_by_user(user)
+        if self.user is None:
+            raise TypeError("Worker not defined for: " + user.username)
+
+        super(AppointmentAddForm, self).__init__(*args, **kwargs)
+        fields = OrderedDict()
+        for i, tuple in enumerate(self.fields.items()):
+            key, value = tuple
+            fields[key] = value
+            if i == APPOINTMENT_TYPES_FIELD_POSITION:
+                fields['appointment_types'] = forms.ModelMultipleChoiceField(required=False,
+                                                                             widget=forms.CheckboxSelectMultiple,
+                                                                             queryset=AppointmentType.objects.all(),
+                                                                             )
+        self.fields = fields
+        self.fields['location'].queryset = get_filter_locations(self.user)
+
+    def clean_location(self):
+        location = self.cleaned_data['location']
+        if self.user.locations.filter(id=location.id).count() == 0:
+            self.add_error('location', "You cannot create appointment for this location")
+        else:
+            return location
+
+    def save(self, commit=True):
+        appointment = super(AppointmentAddForm, self).save(commit)
+        appointment_types = self.cleaned_data['appointment_types']
+        for appointment_type in appointment_types:
+            appointment_type_link = AppointmentTypeLink(appointment=appointment, appointment_type=appointment_type)
+            appointment_type_link.save()
+        return appointment
diff --git a/smash/web/forms/contact_attempt_forms.py b/smash/web/forms/contact_attempt_forms.py
new file mode 100644
index 0000000000000000000000000000000000000000..39bb260e180536b76cf7b8c5e6ca4c59ddc12868
--- /dev/null
+++ b/smash/web/forms/contact_attempt_forms.py
@@ -0,0 +1,45 @@
+from django import forms
+from django.forms import ModelForm
+
+from web.forms.forms import DATETIMEPICKER_DATE_ATTRS
+from web.models import ContactAttempt, Worker
+from web.models.worker_study_role import WORKER_STAFF
+
+
+class ContactAttemptForm(ModelForm):
+    datetime_when = forms.DateTimeField(label='When? (YYYY-MM-DD HH:MM)',
+                                        widget=forms.DateTimeInput(DATETIMEPICKER_DATE_ATTRS)
+                                        )
+
+    def __init__(self, *args, **kwargs):
+        user = kwargs.pop('user', None)
+        if user is None:
+            raise TypeError("User not defined")
+        self.user = Worker.get_by_user(user)
+        if self.user is None:
+            raise TypeError("Worker not defined for: " + user.username)
+        super(ContactAttemptForm, self).__init__(*args, **kwargs)
+        self.fields['subject'].disabled = True
+        self.fields['worker'].queryset = Worker.get_workers_by_worker_type(WORKER_STAFF).distinct().order_by(
+            'first_name', 'last_name')
+
+
+class ContactAttemptAddForm(ContactAttemptForm):
+    class Meta:
+        model = ContactAttempt
+        fields = '__all__'
+
+    def __init__(self, *args, **kwargs):
+        subject = kwargs.pop('subject', None)
+        super(ContactAttemptAddForm, self).__init__(*args, **kwargs)
+        self.fields['subject'].initial = subject.id
+        self.fields['worker'].initial = self.user
+
+
+class ContactAttemptEditForm(ContactAttemptForm):
+    class Meta:
+        model = ContactAttempt
+        fields = '__all__'
+
+    def __init__(self, *args, **kwargs):
+        super(ContactAttemptEditForm, self).__init__(*args, **kwargs)
diff --git a/smash/web/forms/forms.py b/smash/web/forms/forms.py
index 1aa33b920dd8735547cc2b8c786b81ef79e369d6..7fc95986747cdbaf859f928cde493ebd9f53a661 100644
--- a/smash/web/forms/forms.py
+++ b/smash/web/forms/forms.py
@@ -1,6 +1,5 @@
 import datetime
 import logging
-from collections import OrderedDict
 
 from django import forms
 from django.forms import ModelForm, Form
@@ -10,7 +9,6 @@ from web.models import Appointment, AppointmentType, AppointmentTypeLink, \
     Availability, ContactAttempt, FlyingTeam, Holiday, StudySubject, \
     Worker, Visit, VoucherType, VoucherTypePrice
 from web.models.constants import SUBJECT_TYPE_CHOICES
-from web.views.notifications import get_filter_locations
 
 """
 Possible redundancy, but if need arises, contents of forms can be easily customized
@@ -50,145 +48,6 @@ def get_worker_from_args(kwargs):
     return result
 
 
-class WorkerAddForm(ModelForm):
-    class Meta:
-        model = Worker
-        exclude = ['appointments']
-
-
-class WorkerEditForm(ModelForm):
-    class Meta:
-        model = Worker
-        fields = '__all__'
-
-
-class AppointmentDetailForm(ModelForm):
-    class Meta:
-        model = Appointment
-        fields = '__all__'
-
-    datetime_when = forms.DateTimeField(label='Appointment on (YYYY-MM-DD HH:MM)',
-                                        widget=forms.DateTimeInput(DATETIMEPICKER_DATE_ATTRS)
-                                        )
-
-
-class AppointmentEditForm(ModelForm):
-    class Meta:
-        model = Appointment
-        fields = '__all__'
-        exclude = ['appointment_types']
-
-    datetime_when = forms.DateTimeField(label='Appointment on (YYYY-MM-DD HH:MM)',
-                                        widget=forms.DateTimeInput(DATETIMEPICKER_DATE_ATTRS)
-                                        )
-
-    def __init__(self, *args, **kwargs):
-        user = kwargs.pop('user', None)
-        if user is None:
-            raise TypeError("User not defined")
-        self.user = Worker.get_by_user(user)
-        if self.user is None:
-            raise TypeError("Worker not defined for: " + user.username)
-        super(ModelForm, self).__init__(*args, **kwargs)
-        if 'instance' in kwargs:
-            initial_appointment_types = AppointmentTypeLink.objects.filter(appointment=kwargs['instance']).values_list(
-                'appointment_type', flat=True)
-        else:
-            initial_appointment_types = []
-        fields = OrderedDict()
-        for i, tuple in enumerate(self.fields.items()):
-            key, value = tuple
-            fields[key] = value
-            if i == APPOINTMENT_TYPES_FIELD_POSITION:
-                fields['appointment_types'] = forms.ModelMultipleChoiceField(required=False,
-                                                                             widget=forms.CheckboxSelectMultiple,
-                                                                             queryset=AppointmentType.objects.all(),
-                                                                             initial=initial_appointment_types)
-        self.fields = fields
-        self.fields['worker_assigned'].queryset = Worker.objects.filter(
-            locations__in=get_filter_locations(self.user)).distinct().order_by('first_name', 'last_name')
-        self.fields['location'].queryset = get_filter_locations(self.user)
-
-    def clean_location(self):
-        location = self.cleaned_data['location']
-        if self.user.locations.filter(id=location.id).count() == 0:
-            self.add_error('location', "You cannot create appointment for this location")
-        else:
-            return location
-
-    def save(self, commit=True):
-        appointment = super(AppointmentEditForm, self).save(commit)
-        # if appointment date change, remove appointment_type links
-        if 'datetime_when' in self.changed_data:
-            AppointmentTypeLink.objects.filter(appointment=appointment).delete()
-            appointment_type_links = []
-        else:
-            appointment_type_links = AppointmentTypeLink.objects.filter(appointment=appointment).all()
-        appointment_types_from_links = []
-        appointment_types = self.cleaned_data['appointment_types']
-        for appointment_type_link in appointment_type_links:
-            if appointment_type_link.appointment_type not in appointment_types:
-                # we delete appointment links for appointments types that have been removed
-                appointment_type_link.delete()
-            else:
-                appointment_types_from_links.append(appointment_type_link.appointment_type)
-        for appointment_type in appointment_types:
-            if appointment_type not in appointment_types_from_links:
-                # we create new appointment links for appointments types that have been added
-                appointment_type_link = AppointmentTypeLink(appointment=appointment,
-                                                            appointment_type=appointment_type)
-                appointment_type_link.save()
-        return appointment
-
-
-class AppointmentAddForm(ModelForm):
-    class Meta:
-        model = Appointment
-        exclude = ['status', 'appointment_types']
-
-    datetime_when = forms.DateTimeField(label='Appointment on (YYYY-MM-DD HH:MM)',
-                                        widget=forms.DateTimeInput(DATETIMEPICKER_DATE_ATTRS)
-                                        )
-
-    def __init__(self, *args, **kwargs):
-        user = kwargs.pop('user', None)
-        if user is None:
-            raise TypeError("User not defined")
-        self.user = Worker.get_by_user(user)
-        if self.user is None:
-            raise TypeError("Worker not defined for: " + user.username)
-
-        super(ModelForm, self).__init__(*args, **kwargs)
-        fields = OrderedDict()
-        for i, tuple in enumerate(self.fields.items()):
-            key, value = tuple
-            fields[key] = value
-            if i == APPOINTMENT_TYPES_FIELD_POSITION:
-                fields['appointment_types'] = forms.ModelMultipleChoiceField(required=False,
-                                                                             widget=forms.CheckboxSelectMultiple,
-                                                                             queryset=AppointmentType.objects.all(),
-                                                                             )
-        self.fields = fields
-        self.fields['worker_assigned'].queryset = Worker.objects.filter(
-            locations__in=get_filter_locations(self.user)).distinct().order_by('first_name', 'last_name')
-        self.fields['location'].queryset = get_filter_locations(self.user)
-
-    def clean_location(self):
-        location = self.cleaned_data['location']
-        if self.user.locations.filter(id=location.id).count() == 0:
-            self.add_error('location', "You cannot create appointment for this location")
-        else:
-            return location
-
-    def save(self, commit=True):
-        appointment = super(AppointmentAddForm, self).save(commit)
-        appointment_types = self.cleaned_data['appointment_types']
-        for appointment_type in appointment_types:
-            appointment_type_link = AppointmentTypeLink(appointment=appointment, appointment_type=appointment_type)
-            appointment_type_link.save()
-        return appointment
-
-
 class VisitDetailForm(ModelForm):
     datetime_begin = forms.DateField(label="Visit begins on",
                                      widget=forms.DateInput(DATEPICKER_DATE_ATTRS, "%Y-%m-%d")
@@ -231,49 +90,6 @@ class VisitAddForm(ModelForm):
             self.add_error('datetime_end', "End date must be after start date")
 
 
-class ContactAttemptForm(ModelForm):
-    datetime_when = forms.DateTimeField(label='When? (YYYY-MM-DD HH:MM)',
-                                        widget=forms.DateTimeInput(DATETIMEPICKER_DATE_ATTRS)
-                                        )
-
-    class Meta:
-        model = ContactAttempt
-        fields = '__all__'
-
-    def __init__(self, *args, **kwargs):
-        user = kwargs.pop('user', None)
-        if user is None:
-            raise TypeError("User not defined")
-        self.user = Worker.get_by_user(user)
-        if self.user is None:
-            raise TypeError("Worker not defined for: " + user.username)
-        subject = kwargs.pop('subject', None)
-        super(ContactAttemptForm, self).__init__(*args, **kwargs)
-        self.fields['subject'].initial = subject.id
-        self.fields['subject'].disabled = True
-        self.fields['worker'].initial = self.user
-
-
-class ContactAttemptEditForm(ModelForm):
-    datetime_when = forms.DateTimeField(label='When? (YYYY-MM-DD HH:MM)',
-                                        widget=forms.DateTimeInput(DATETIMEPICKER_DATE_ATTRS)
-                                        )
-
-    class Meta:
-        model = ContactAttempt
-        fields = '__all__'
-
-    def __init__(self, *args, **kwargs):
-        user = kwargs.pop('user', None)
-        if user is None:
-            raise TypeError("User not defined")
-        self.user = Worker.get_by_user(user)
-        if self.user is None:
-            raise TypeError("Worker not defined for: " + user.username)
-        super(ContactAttemptEditForm, self).__init__(*args, **kwargs)
-        self.fields['subject'].disabled = True
-
-
 class KitRequestForm(Form):
     start_date = forms.DateField(label="From date",
                                  widget=forms.DateInput(DATEPICKER_DATE_ATTRS, "%Y-%m-%d"),
@@ -398,5 +214,3 @@ class HolidayAddForm(ModelForm):
         availabilities = worker.availability_set.all()
         for availability in availabilities:
             validate_availability_conflict(self, self.cleaned_data, availability)
-
-
diff --git a/smash/web/forms/study_subject_forms.py b/smash/web/forms/study_subject_forms.py
index 94fa1fcfe15551d3d9510337db6ad1828158ca24..7101e6bbeec368de1979c6f901b033b9f96cd8b4 100644
--- a/smash/web/forms/study_subject_forms.py
+++ b/smash/web/forms/study_subject_forms.py
@@ -5,8 +5,9 @@ from django import forms
 from django.forms import ModelForm
 
 from web.forms.forms import DATETIMEPICKER_DATE_ATTRS, get_worker_from_args
-from web.models import StudySubject, Study, StudyColumns, VoucherType
+from web.models import StudySubject, Study, StudyColumns, VoucherType, Worker
 from web.models.constants import SCREENING_NUMBER_PREFIXES_FOR_TYPE
+from web.models.worker_study_role import WORKER_HEALTH_PARTNER
 from web.widgets.secure_file_widget import SecuredFileWidget
 
 logger = logging.getLogger(__name__)
@@ -27,6 +28,7 @@ class StudySubjectForm(ModelForm):
 
     def __init__(self, *args, **kwargs):
         super(StudySubjectForm, self).__init__(*args, **kwargs)
+        self.fields['health_partner'].queryset = Worker.get_workers_by_worker_type(WORKER_HEALTH_PARTNER)
 
 
 class StudySubjectAddForm(StudySubjectForm):
diff --git a/smash/web/forms/voucher_forms.py b/smash/web/forms/voucher_forms.py
index 99bb89736762a3c49a1e859d95feb0389f033fa9..946486db177dd364d547e97afba6b33fafbc9bc2 100644
--- a/smash/web/forms/voucher_forms.py
+++ b/smash/web/forms/voucher_forms.py
@@ -7,8 +7,9 @@ from django.utils import timezone
 
 from web.algorithm import VerhoeffAlgorithm
 from web.forms.forms import DATEPICKER_DATE_ATTRS
-from web.models import VoucherType, VoucherTypePrice, Voucher
+from web.models import VoucherType, VoucherTypePrice, Voucher, Worker
 from web.models.constants import VOUCHER_STATUS_NEW, VOUCHER_STATUS_USED
+from web.models.worker_study_role import WORKER_VOUCHER_PARTNER
 
 logger = logging.getLogger(__name__)
 
@@ -42,6 +43,7 @@ class VoucherForm(ModelForm):
         super(VoucherForm, self).__init__(*args, **kwargs)
 
         self.fields['voucher_type'].queryset = voucher_types
+        self.fields['usage_partner'].queryset = Worker.get_workers_by_worker_type(WORKER_VOUCHER_PARTNER)
 
         self.fields['number'].widget.attrs['readonly'] = True
         self.fields['number'].required = False
diff --git a/smash/web/forms/worker_form.py b/smash/web/forms/worker_form.py
new file mode 100644
index 0000000000000000000000000000000000000000..5fd4da53b15d4806e64230ce855a2ea6d6e93373
--- /dev/null
+++ b/smash/web/forms/worker_form.py
@@ -0,0 +1,45 @@
+import logging
+
+from django import forms
+from django.forms import ModelForm
+
+from web.models import Worker, WorkerStudyRole
+from web.models.constants import GLOBAL_STUDY_ID
+from web.models.worker import role_choices_by_worker_type, worker_type_by_worker
+from web.models.worker_study_role import WORKER_STAFF
+
+logger = logging.getLogger(__name__)
+
+
+class WorkerForm(ModelForm):
+    class Meta:
+        model = Worker
+        exclude = ['appointments']
+
+    def __init__(self, *args, **kwargs):
+        worker_type = kwargs.pop('worker_type', WORKER_STAFF)
+        super(WorkerForm, self).__init__(*args, **kwargs)
+        instance = getattr(self, 'instance', None)
+
+        initial_role = None
+        if instance is not None:
+            worker_type = worker_type_by_worker(instance)
+            roles = WorkerStudyRole.objects.filter(worker=instance, study_id=GLOBAL_STUDY_ID)
+
+            if roles.count() > 0:
+                initial_role = roles[0].role
+
+        choices = role_choices_by_worker_type(worker_type)
+        self.fields['role'] = forms.ChoiceField(label='Role', choices=choices)
+        self.fields['role'].initial = initial_role
+
+        if worker_type == WORKER_STAFF:
+            del self.fields['voucher_types']
+
+    def save(self, commit=True):
+        instance = super(WorkerForm, self).save(commit)
+        roles = WorkerStudyRole.objects.filter(worker=instance, study_id=GLOBAL_STUDY_ID)
+        if roles.count() > 0:
+            roles.update(role=self.cleaned_data['role'])
+        else:
+            WorkerStudyRole.objects.create(worker=instance, study_id=GLOBAL_STUDY_ID, role=self.cleaned_data['role'])
diff --git a/smash/web/migrations/0098_workerstudyrole.py b/smash/web/migrations/0098_workerstudyrole.py
new file mode 100644
index 0000000000000000000000000000000000000000..247c4ad401d6407649a19c6b4936f5ed3f4d210c
--- /dev/null
+++ b/smash/web/migrations/0098_workerstudyrole.py
@@ -0,0 +1,32 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.7 on 2017-12-12 14:15
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('web', '0097_auto_20171211_1616'),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name='WorkerStudyRole',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('role', models.CharField(choices=[(b'DOCTOR', b'Doctor'), (b'NURSE', b'Nurse'), (b'PSYCHOLOGIST', b'Psychologist'), (b'TECHNICIAN', b'Technician'), (b'SECRETARY', b'Secretary')], max_length=20, verbose_name=b'Role')),
+                ('study', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='web.Study')),
+                ('worker', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='roles', to='web.Worker')),
+            ],
+        ),
+        migrations.RunSQL('insert into web_workerstudyrole (study_id, worker_id, role) '+
+                          'select 1, id, role from web_worker;'),
+        migrations.RemoveField(
+            model_name='worker',
+            name='role',
+        ),
+
+    ]
diff --git a/smash/web/migrations/0099_auto_20171213_1115.py b/smash/web/migrations/0099_auto_20171213_1115.py
new file mode 100644
index 0000000000000000000000000000000000000000..36f7df053335eaaf12b53d29195e6160dcc2d171
--- /dev/null
+++ b/smash/web/migrations/0099_auto_20171213_1115.py
@@ -0,0 +1,40 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.7 on 2017-12-13 11:15
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('web', '0098_workerstudyrole'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='worker',
+            name='languages',
+            field=models.ManyToManyField(blank=True, to='web.Language', verbose_name=b'Known languages'),
+        ),
+        migrations.AlterField(
+            model_name='worker',
+            name='locations',
+            field=models.ManyToManyField(blank=True, to='web.Location', verbose_name=b'Locations'),
+        ),
+        migrations.AlterField(
+            model_name='worker',
+            name='phone_number',
+            field=models.CharField(blank=True, max_length=20, verbose_name=b'Phone number'),
+        ),
+        migrations.AlterField(
+            model_name='worker',
+            name='specialization',
+            field=models.CharField(blank=True, max_length=20, verbose_name=b'Specialization'),
+        ),
+        migrations.AlterField(
+            model_name='worker',
+            name='unit',
+            field=models.CharField(blank=True, max_length=50, verbose_name=b'Unit'),
+        ),
+    ]
diff --git a/smash/web/migrations/0100_auto_20171213_1140.py b/smash/web/migrations/0100_auto_20171213_1140.py
new file mode 100644
index 0000000000000000000000000000000000000000..6bacef3d9db5c8a66ca87363c89cf0c37ffc13a1
--- /dev/null
+++ b/smash/web/migrations/0100_auto_20171213_1140.py
@@ -0,0 +1,51 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.7 on 2017-12-13 11:40
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('web', '0099_auto_20171213_1115'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='worker',
+            name='address',
+            field=models.CharField(blank=True, max_length=255, verbose_name=b'Address'),
+        ),
+        migrations.AddField(
+            model_name='worker',
+            name='city',
+            field=models.CharField(blank=True, max_length=50, verbose_name=b'City'),
+        ),
+        migrations.AddField(
+            model_name='worker',
+            name='country',
+            field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, to='web.Country', verbose_name=b'Country'),
+        ),
+        migrations.AddField(
+            model_name='worker',
+            name='fax_number',
+            field=models.CharField(blank=True, max_length=20, verbose_name=b'Fax number'),
+        ),
+        migrations.AddField(
+            model_name='worker',
+            name='phone_number_2',
+            field=models.CharField(blank=True, max_length=20, verbose_name=b'Phone number 2'),
+        ),
+        migrations.AddField(
+            model_name='worker',
+            name='postal_code',
+            field=models.CharField(blank=True, max_length=7, verbose_name=b'Postal code'),
+        ),
+        migrations.AddField(
+            model_name='worker',
+            name='voucher_types',
+            field=models.ManyToManyField(blank=True, to='web.VoucherType', verbose_name=b'Voucher types'),
+        ),
+    ]
diff --git a/smash/web/models/__init__.py b/smash/web/models/__init__.py
index 77a30db094dfd4b977b2ca164a0070b39ea1e8cc..9edb9cb0982da082f3fd3011ce76607ae0970748 100644
--- a/smash/web/models/__init__.py
+++ b/smash/web/models/__init__.py
@@ -19,6 +19,7 @@ from voucher_type_price import VoucherTypePrice
 from room import Room
 from visit import Visit
 from worker import Worker
+from worker_study_role import WorkerStudyRole
 from appointment import Appointment
 from appointment_type import AppointmentType
 from availability import Availability
@@ -39,5 +40,5 @@ from inconsistent_subject import InconsistentSubject, InconsistentField
 __all__ = [Study, FlyingTeam, Appointment, AppointmentType, Availability, Holiday, Item, Language, Location, Room,
            Subject, StudySubject, StudySubjectList, SubjectColumns, StudyNotificationParameters,
            AppointmentList, AppointmentColumns, Visit, Worker, ContactAttempt, ConfigurationItem, MailTemplate,
-           AppointmentTypeLink, VoucherType, VoucherTypePrice, Voucher,
+           AppointmentTypeLink, VoucherType, VoucherTypePrice, Voucher, WorkerStudyRole,
            MissingSubject, InconsistentSubject, InconsistentField, Country, StudyColumns, VisitColumns, StudyVisitList]
diff --git a/smash/web/models/visit.py b/smash/web/models/visit.py
index 61b29704181cff23b8091e5fb43c0e01232a3e88..2922ea8bb66ba4e71fd213edd5ff660be87f9304 100644
--- a/smash/web/models/visit.py
+++ b/smash/web/models/visit.py
@@ -5,7 +5,7 @@ from django.db import models
 from django.db.models.signals import post_save
 from django.dispatch import receiver
 
-from constants import BOOL_CHOICES, SUBJECT_TYPE_CHOICES_CONTROL
+from web.models.constants import BOOL_CHOICES, SUBJECT_TYPE_CHOICES_CONTROL
 
 
 class Visit(models.Model):
diff --git a/smash/web/models/worker.py b/smash/web/models/worker.py
index 8923532e3351205d48ed2e7b8fe0419b670d2efe..df02e89f21972de2dedb04832cff24c3b113773e 100644
--- a/smash/web/models/worker.py
+++ b/smash/web/models/worker.py
@@ -5,18 +5,61 @@ import logging
 from django.contrib.auth.models import User, AnonymousUser
 from django.db import models
 
+from web.models.constants import GLOBAL_STUDY_ID, COUNTRY_OTHER_ID
+from web.models.worker_study_role import STUDY_ROLE_CHOICES, HEALTH_PARTNER_ROLE_CHOICES, \
+    VOUCHER_PARTNER_ROLE_CHOICES, WORKER_STAFF, WORKER_HEALTH_PARTNER, WORKER_VOUCHER_PARTNER
+
 logger = logging.getLogger(__name__)
 
 
+def roles_by_worker_type(worker_type):
+    role_choices = role_choices_by_worker_type(worker_type)
+    roles = []
+
+    for role_type, role_name in role_choices:
+        roles.append(role_type)
+    return roles
+
+
+def role_choices_by_worker_type(worker_type):
+    if worker_type == WORKER_STAFF:
+        return STUDY_ROLE_CHOICES
+    elif worker_type == WORKER_HEALTH_PARTNER:
+        return HEALTH_PARTNER_ROLE_CHOICES
+    elif worker_type == WORKER_VOUCHER_PARTNER:
+        return VOUCHER_PARTNER_ROLE_CHOICES
+    else:
+        raise TypeError("Unknown worker type")
+
+
+def worker_type_by_worker(worker):
+    roles = worker.roles.filter(study=GLOBAL_STUDY_ID)
+    if roles.count() == 0:
+        return WORKER_STAFF
+    role = roles[0].role
+    for role_type, role_name in STUDY_ROLE_CHOICES:
+        if role_type == role:
+            return WORKER_STAFF
+    for role_type, role_name in HEALTH_PARTNER_ROLE_CHOICES:
+        if role_type == role:
+            return WORKER_HEALTH_PARTNER
+    for role_type, role_name in VOUCHER_PARTNER_ROLE_CHOICES:
+        if role_type == role:
+            return WORKER_VOUCHER_PARTNER
+    raise TypeError("Unknown worker role")
+
+
 class Worker(models.Model):
     class Meta:
         app_label = 'web'
 
     languages = models.ManyToManyField("web.Language",
-                                       verbose_name='Known languages'
+                                       verbose_name='Known languages',
+                                       blank=True
                                        )
     locations = models.ManyToManyField("web.Location",
-                                       verbose_name='Locations'
+                                       verbose_name='Locations',
+                                       blank=True
                                        )
     appointments = models.ManyToManyField('web.Appointment', blank=True,
                                           verbose_name='Appointments'
@@ -31,29 +74,55 @@ class Worker(models.Model):
                                  verbose_name='Last name'
                                  )
     phone_number = models.CharField(max_length=20,
-                                    verbose_name='Phone number'
+                                    verbose_name='Phone number',
+                                    blank=True
                                     )
+    phone_number_2 = models.CharField(max_length=20,
+                                      verbose_name='Phone number 2',
+                                      blank=True
+                                      )
+    fax_number = models.CharField(max_length=20,
+                                  verbose_name='Fax number',
+                                  blank=True
+                                  )
+    address = models.CharField(max_length=255,
+                               blank=True,
+                               verbose_name='Address'
+                               )
+
+    postal_code = models.CharField(max_length=7,
+                                   blank=True,
+                                   verbose_name='Postal code'
+                                   )
+
+    city = models.CharField(max_length=50,
+                            blank=True,
+                            verbose_name='City'
+                            )
+
+    country = models.ForeignKey('web.Country',
+                                null=False,
+                                blank=False,
+                                default=COUNTRY_OTHER_ID,
+                                verbose_name='Country'
+                                )
+
+    voucher_types = models.ManyToManyField("web.VoucherType",
+                                           verbose_name='Voucher types',
+                                           blank=True
+                                           )
+
     unit = models.CharField(max_length=50,
-                            verbose_name='Unit'
+                            verbose_name='Unit',
+                            blank=True
                             )
     email = models.EmailField(
         verbose_name='E-mail'
     )
 
-    ROLE_CHOICES_SECRETARY = "SECRETARY"
-    ROLE_CHOICES_DOCTOR = "DOCTOR"
-    ROLE_CHOICES = (
-        (ROLE_CHOICES_DOCTOR, 'Doctor'),
-        ('NURSE', 'Nurse'),
-        ('PSYCHOLOGIST', 'Psychologist'),
-        ('TECHNICIAN', 'Technician'),
-        (ROLE_CHOICES_SECRETARY, 'Secretary')
-    )
-    role = models.CharField(max_length=20, choices=ROLE_CHOICES,
-                            verbose_name='Role'
-                            )
     specialization = models.CharField(max_length=20,
-                                      verbose_name='Specialization'
+                                      verbose_name='Specialization',
+                                      blank=True
                                       )
 
     def is_on_leave(self):
@@ -95,16 +164,23 @@ class Worker(models.Model):
         else:
             return None
 
+    @staticmethod
+    def get_workers_by_worker_type(worker_type, study_id=GLOBAL_STUDY_ID):
+        return Worker.objects.filter(roles__study_id=study_id,
+                                     roles__role__in=roles_by_worker_type(worker_type))
+
     @staticmethod
     def get_details(the_user):
-        person = Worker.objects.filter(user=the_user)
+        persons = Worker.objects.filter(user=the_user)
 
-        if len(person) == 0:
+        if len(persons) == 0:
             return the_user.get_full_name(), '<No worker information>'
         else:
-            # For get_*_display, see:
-            # https://docs.djangoproject.com/en/1.10/topics/db/models/#field-options
-            return unicode(person[0]), person[0].get_role_display()
+            person = persons[0]
+            role = "N/A"
+            if person.roles.filter(study=GLOBAL_STUDY_ID).count() > 0:
+                role = person.roles.filter(study=GLOBAL_STUDY_ID)[0].get_role_display()
+            return unicode(person), role
 
     def __str__(self):
         return "%s %s" % (self.first_name, self.last_name)
diff --git a/smash/web/models/worker_study_role.py b/smash/web/models/worker_study_role.py
new file mode 100644
index 0000000000000000000000000000000000000000..c6e6654e70b3bd7c7c671ac18347928f733b0aa4
--- /dev/null
+++ b/smash/web/models/worker_study_role.py
@@ -0,0 +1,52 @@
+# coding=utf-8
+import logging
+
+from django.db import models
+
+logger = logging.getLogger(__name__)
+
+ROLE_CHOICES_SECRETARY = "SECRETARY"
+ROLE_CHOICES_DOCTOR = "DOCTOR"
+ROLE_CHOICES_NURSE = "NURSE"
+ROLE_CHOICES_PSYCHOLOGIST = "PSYCHOLOGIST"
+ROLE_CHOICES_TECHNICIAN = "TECHNICIAN"
+
+ROLE_CHOICES_HEALTH_PARTNER = "HEALTH_PARTNER"
+ROLE_CHOICES_VOUCHER_PARTNER = "VOUCHER_PARTNER"
+
+STUDY_ROLE_CHOICES = (
+    (ROLE_CHOICES_DOCTOR, 'Doctor'),
+    (ROLE_CHOICES_NURSE, 'Nurse'),
+    (ROLE_CHOICES_PSYCHOLOGIST, 'Psychologist'),
+    (ROLE_CHOICES_TECHNICIAN, 'Technician'),
+    (ROLE_CHOICES_SECRETARY, 'Secretary')
+)
+
+HEALTH_PARTNER_ROLE_CHOICES = (
+    (ROLE_CHOICES_HEALTH_PARTNER, "Health Partner"),
+)
+
+VOUCHER_PARTNER_ROLE_CHOICES = (
+    (ROLE_CHOICES_VOUCHER_PARTNER, "Voucher Partner"),
+)
+
+ROLE_CHOICES = STUDY_ROLE_CHOICES + HEALTH_PARTNER_ROLE_CHOICES + VOUCHER_PARTNER_ROLE_CHOICES
+
+WORKER_STAFF = "STAFF"
+WORKER_HEALTH_PARTNER = "HEALTH_PARTNER"
+WORKER_VOUCHER_PARTNER = "VOUCHER_PARTNER"
+
+
+class WorkerStudyRole(models.Model):
+    class Meta:
+        app_label = 'web'
+
+    worker = models.ForeignKey("web.Worker",
+                               related_name="roles"
+                               )
+
+    study = models.ForeignKey("web.Study")
+
+    role = models.CharField(max_length=20, choices=STUDY_ROLE_CHOICES,
+                            verbose_name='Role'
+                            )
diff --git a/smash/web/templates/doctors/add.html b/smash/web/templates/doctors/add.html
index eb17a92775c2ae3206b8545d674c9b2614361274..45259a6242701e7754fcf98eea71b6609fa3da19 100644
--- a/smash/web/templates/doctors/add.html
+++ b/smash/web/templates/doctors/add.html
@@ -22,7 +22,7 @@
     {% block content %}
         <div class="box box-info">
             <div class="box-header with-border">
-                <a href="{% url 'web.views.doctors' %}" class="btn btn-block btn-default">Go back (without changes)</a>
+                <a href="{% url 'web.views.workers' %}" class="btn btn-block btn-default">Go back (without changes)</a>
             </div>
 
             <form method="post" action="" class="form-horizontal">
@@ -55,7 +55,7 @@
                         <button type="submit" class="btn btn-block btn-success">Add</button>
                     </div>
                     <div class="col-sm-6">
-                        <a href="{% url 'web.views.doctors' %}" class="btn btn-block btn-default">Cancel</a>
+                        <a href="{% url 'web.views.workers' %}" class="btn btn-block btn-default">Cancel</a>
                     </div>
                 </div><!-- /.box-footer -->
             </form>
diff --git a/smash/web/templates/doctors/add_availability.html b/smash/web/templates/doctors/add_availability.html
index 3277b6f0db6c2f21bf7216cbaaff85a5cc5089e6..de6dce582dd2ea09ae2faf06b1d29bf4c21d0e03 100644
--- a/smash/web/templates/doctors/add_availability.html
+++ b/smash/web/templates/doctors/add_availability.html
@@ -22,7 +22,7 @@
     {% block content %}
         <div class="box box-info">
             <div class="box-header with-border">
-                <a href="{% url 'web.views.doctor_edit' doctor_id %}" class="btn btn-block btn-default">Go back (without
+                <a href="{% url 'web.views.worker_edit' doctor_id %}" class="btn btn-block btn-default">Go back (without
                     changes)</a>
             </div>
 
@@ -56,7 +56,7 @@
                         <button type="submit" class="btn btn-block btn-success">Add</button>
                     </div>
                     <div class="col-sm-6">
-                        <a href="{% url 'web.views.doctor_edit' doctor_id %}"
+                        <a href="{% url 'web.views.worker_edit' doctor_id %}"
                            class="btn btn-block btn-default">Cancel</a>
                     </div>
                 </div><!-- /.box-footer -->
diff --git a/smash/web/templates/doctors/add_holiday.html b/smash/web/templates/doctors/add_holiday.html
index 797bab7d47ad70f20606fd0c71805e53f6e2e0b5..59e2975087f29fa7adf00f386bf03623c09966f5 100644
--- a/smash/web/templates/doctors/add_holiday.html
+++ b/smash/web/templates/doctors/add_holiday.html
@@ -23,7 +23,7 @@
     {% block content %}
         <div class="box box-info">
             <div class="box-header with-border">
-                <a href="{% url 'web.views.doctor_edit' doctor_id %}" class="btn btn-block btn-default">Go back (without
+                <a href="{% url 'web.views.worker_edit' doctor_id %}" class="btn btn-block btn-default">Go back (without
                     changes)</a>
             </div>
 
@@ -57,7 +57,7 @@
                         <button type="submit" class="btn btn-block btn-success">Add</button>
                     </div>
                     <div class="col-sm-6">
-                        <a href="{% url 'web.views.doctor_edit' doctor_id %}"
+                        <a href="{% url 'web.views.worker_edit' doctor_id %}"
                            class="btn btn-block btn-default">Cancel</a>
                     </div>
                 </div><!-- /.box-footer -->
diff --git a/smash/web/templates/doctors/breadcrumb.html b/smash/web/templates/doctors/breadcrumb.html
index 76b5b72095b33b9a7c470f19bb7568d72b7df9b4..6d111dd545adc0d422fe4dfae996671af3c8f657 100644
--- a/smash/web/templates/doctors/breadcrumb.html
+++ b/smash/web/templates/doctors/breadcrumb.html
@@ -1,2 +1,2 @@
 <li><a href="{% url 'web.views.appointments' %}"><i class="fa fa-dashboard"></i> Dashboard</a></li>
-<li class="active"><a href="{% url 'web.views.doctors' %}">Workers</a></li>
\ No newline at end of file
+<li class="active"><a href="{% url 'web.views.workers' %}">Workers</a></li>
\ No newline at end of file
diff --git a/smash/web/templates/doctors/edit.html b/smash/web/templates/doctors/edit.html
index e41beaed77e99201e1f6fcbb5c865c13a0f83812..148cda2c28482fd8327a800c334d58728abf9cb6 100644
--- a/smash/web/templates/doctors/edit.html
+++ b/smash/web/templates/doctors/edit.html
@@ -23,7 +23,7 @@
     {% block content %}
         <div class="box box-info">
             <div class="box-header with-border">
-                <a href="{% url 'web.views.doctors' %}" class="btn btn-block btn-default" onclick="history.back()">Go
+                <a href="{% url 'web.views.workers' %}" class="btn btn-block btn-default" onclick="history.back()">Go
                     back (without changes)</a>
             </div>
 
@@ -55,7 +55,7 @@
                         <button type="submit" class="btn btn-block btn-success">Save</button>
                     </div>
                     <div class="col-sm-6">
-                        <a href="{% url 'web.views.doctors' %}" class="btn btn-block btn-default"
+                        <a href="{% url 'web.views.workers' %}" class="btn btn-block btn-default"
                            onclick="history.back()">Cancel</a>
                     </div>
                 </div><!-- /.box-footer -->
@@ -90,11 +90,11 @@
                         <td>{{ availability.available_from }}</td>
                         <td>{{ availability.available_till }}</td>
                         <td>
-                            <a href="{% url 'web.views.doctor_availability_edit' availability.id %}" type="button"
+                            <a href="{% url 'web.views.worker_availability_edit' availability.id %}" type="button"
                                class="btn btn-block btn-default">Edit</a>
                         </td>
                         <td>
-                            <a href="{% url 'web.views.doctor_availability_delete' availability.id %}" type="button"
+                            <a href="{% url 'web.views.worker_availability_delete' availability.id %}" type="button"
                                class="btn btn-block btn-default">Delete</a>
                         </td>
                     </tr>
@@ -105,7 +105,7 @@
 
             <div class="box-footer">
                 <div class="col-sm-6">
-                    <a href="{% url 'views.doctor.doctor_availability_add' doctor_id %}" type="button"
+                    <a href="{% url 'web.views.worker_availability_add' doctor_id %}" type="button"
                        class="btn btn-block btn-success">Add availability</a>
                 </div>
             </div><!-- /.box-footer -->
@@ -132,7 +132,7 @@
                         <td>{{ holiday.datetime_end }}</td>
                         <td>{{ holiday.info }}</td>
                         <td>
-                            <a href="{% url 'web.views.doctor_holiday_delete' holiday.id %}" type="button"
+                            <a href="{% url 'web.views.worker_holiday_delete' holiday.id %}" type="button"
                                class="btn btn-block btn-default">Delete</a>
                         </td>
                     </tr>
@@ -143,7 +143,7 @@
 
             <div class="box-footer">
                 <div class="col-sm-6">
-                    <a href="{% url 'views.doctor.doctor_holiday_add' doctor_id %}" type="button"
+                    <a href="{% url 'web.views.worker_holiday_add' doctor_id %}" type="button"
                        class="btn btn-block btn-success">Add holiday</a>
                 </div>
             </div><!-- /.box-footer -->
diff --git a/smash/web/templates/doctors/edit_availability.html b/smash/web/templates/doctors/edit_availability.html
index 37de10ae4cc064b45b0173ef53d7a80e43296227..4daf5fffd8475f40a0908e700dfb717547c36a24 100644
--- a/smash/web/templates/doctors/edit_availability.html
+++ b/smash/web/templates/doctors/edit_availability.html
@@ -23,7 +23,7 @@
     {% block content %}
         <div class="box box-info">
             <div class="box-header with-border">
-                <a href="{% url 'web.views.doctor_edit' doctor_id %}" class="btn btn-block btn-default">Go back (without
+                <a href="{% url 'web.views.worker_edit' doctor_id %}" class="btn btn-block btn-default">Go back (without
                     changes)</a>
             </div>
 
@@ -57,7 +57,7 @@
                         <button type="submit" class="btn btn-block btn-success">Save</button>
                     </div>
                     <div class="col-sm-6">
-                        <a href="{% url 'web.views.doctor_edit' doctor_id %}"
+                        <a href="{% url 'web.views.worker_edit' doctor_id %}"
                            class="btn btn-block btn-default">Cancel</a>
                     </div>
                 </div><!-- /.box-footer -->
diff --git a/smash/web/templates/doctors/index.html b/smash/web/templates/doctors/index.html
index 4dc34ec01d556867dd728b5f51d553f360eceb0c..67741a4b3b3fbf193e98e6c77c5a44db981ba3f9 100644
--- a/smash/web/templates/doctors/index.html
+++ b/smash/web/templates/doctors/index.html
@@ -18,7 +18,7 @@
 {% block maincontent %}
 
     <div>
-        <a href="{% url 'web.views.doctor_add' %}" class="btn btn-app">
+        <a href="{% url 'web.views.worker_add' worker_type %}" class="btn btn-app">
             <i class="fa fa-plus"></i>
             Add new worker</a>
     </div>
@@ -52,7 +52,7 @@
                             {% endautoescape %}
                         </td>
                         <td>{{ worker.unit }}</td>
-                        <td><a href="{% url 'web.views.doctor_edit' worker.id %}" type="button"
+                        <td><a href="{% url 'web.views.worker_edit' worker.id %}" type="button"
                                class="btn btn-block btn-default">Details</a></td>
                         <td>
                             {% if worker.is_on_leave %}
@@ -63,7 +63,7 @@
                         </td>
                         <td>
                             {% if worker.is_active %}
-                                <a href="{% url 'web.views.doctor_disable' worker.id %}" class="btn btn-block btn-warning">DISABLE</a>
+                                <a href="{% url 'web.views.worker_disable' worker.id %}" class="btn btn-block btn-warning">DISABLE</a>
                             {% else %}
                                 YES
                             {% endif %}
diff --git a/smash/web/templates/sidebar.html b/smash/web/templates/sidebar.html
index 05498fc5bf407bdd307a8e554214a598a5105953..235006d25e2c473796090189adc1e11426fcbf59 100644
--- a/smash/web/templates/sidebar.html
+++ b/smash/web/templates/sidebar.html
@@ -24,7 +24,7 @@
     </li>
 
     <li data-desc="workers">
-        <a href="{% url 'web.views.doctors' %}">
+        <a href="{% url 'web.views.workers' %}">
             <i class="fa fa-user-md"></i>
             <span>Workers</span>
         </a>
diff --git a/smash/web/tests/api_views/test_daily_planning.py b/smash/web/tests/api_views/test_daily_planning.py
index 0d48c8d15ed527d6704f168a77cdd0b47f94dfad..5f2cce562debb2cccda3bb876673b78cdb1431ac 100644
--- a/smash/web/tests/api_views/test_daily_planning.py
+++ b/smash/web/tests/api_views/test_daily_planning.py
@@ -1,30 +1,23 @@
 # coding=utf-8
 import datetime
 import json
+import logging
 
 from django.contrib.auth.models import User
-from django.test import Client, RequestFactory
-from django.test import TestCase
+from django.test import RequestFactory
 from django.urls import reverse
 
+from web.tests import LoggedInWithWorkerTestCase
 from web.api_views.daily_planning import get_workers_for_daily_planning, get_generic_appointment_events
-from web.models import Worker, Availability, Holiday, AppointmentTypeLink
+from web.models import Availability, Holiday, AppointmentTypeLink
 from web.models.constants import TUESDAY_AS_DAY_OF_WEEK
 from web.tests.functions import create_worker, create_study_subject, create_appointment, create_flying_team, \
     create_visit, create_appointment_type, get_test_location
 
+logger = logging.getLogger(__name__)
 
-class TestApi(TestCase):
-    def setUp(self):
-        self.client = Client()
-        username = 'piotr'
-        password = 'top_secret'
-        self.user = User.objects.create_user(
-            username=username, email='jacob@bla', password=password)
-        self.worker = create_worker(self.user, True)
-        self.worker.role = Worker.ROLE_CHOICES_DOCTOR
-        self.worker.save()
-        self.client.login(username=username, password=password)
+
+class TestDailyPlanningApi(LoggedInWithWorkerTestCase):
 
     def test_empty_availabilities(self):
         response = self.client.get(reverse('web.api.events', kwargs={'date': "2017-09-05"}))
diff --git a/smash/web/tests/api_views/test_worker.py b/smash/web/tests/api_views/test_worker.py
index 0b32a0b321347ea85467de611b981e1d551508b7..22b8e76eec524117da068ee506cc020ff8bf569f 100644
--- a/smash/web/tests/api_views/test_worker.py
+++ b/smash/web/tests/api_views/test_worker.py
@@ -10,7 +10,7 @@ from web.api_views.worker import availabilities
 from web.tests import LoggedInWithWorkerTestCase
 
 
-class TestApi(LoggedInWithWorkerTestCase):
+class TestWorkerApi(LoggedInWithWorkerTestCase):
     def test_specializations(self):
         specialization_name = "some spec"
 
diff --git a/smash/web/tests/forms/test_AppointmentEditForm.py b/smash/web/tests/forms/test_AppointmentEditForm.py
index f62fe60937dcb10e313d273f93e3a908619d1b88..ff8140c0db4c7d5dca4a071d6fc34713d7f62559 100644
--- a/smash/web/tests/forms/test_AppointmentEditForm.py
+++ b/smash/web/tests/forms/test_AppointmentEditForm.py
@@ -1,7 +1,6 @@
 from django.test import TestCase
 
-from web.forms import AppointmentAddForm
-from web.forms import AppointmentEditForm
+from web.forms import AppointmentEditForm, AppointmentAddForm
 from web.models import Appointment, Worker, AppointmentTypeLink
 from web.tests.functions import get_test_location, create_user, create_visit, create_location, create_appointment_type
 
diff --git a/smash/web/tests/forms/test_voucher_forms.py b/smash/web/tests/forms/test_voucher_forms.py
index 64a78eef15b2365f515aecfa030b4da88aaeb166..ef712cfd73ce50411dced4da76f553eced508b16 100644
--- a/smash/web/tests/forms/test_voucher_forms.py
+++ b/smash/web/tests/forms/test_voucher_forms.py
@@ -3,10 +3,12 @@ import logging
 from django.urls import reverse
 
 from web.forms import VoucherForm
-from web.models import Voucher
+from web.models import WorkerStudyRole, Voucher
 from web.models.constants import VOUCHER_STATUS_USED
+from web.models.worker_study_role import ROLE_CHOICES_VOUCHER_PARTNER
 from web.tests import LoggedInWithWorkerTestCase
-from web.tests.functions import create_study_subject, create_voucher_type, format_form_field, create_voucher
+from web.tests.functions import create_study_subject, create_voucher_type, format_form_field, create_voucher, \
+    create_worker
 
 logger = logging.getLogger(__name__)
 
@@ -14,6 +16,8 @@ logger = logging.getLogger(__name__)
 class VoucherFormTests(LoggedInWithWorkerTestCase):
     def setUp(self):
         super(VoucherFormTests, self).setUp()
+        self.voucher_partner = create_worker()
+        WorkerStudyRole.objects.filter(worker=self.voucher_partner).update(role=ROLE_CHOICES_VOUCHER_PARTNER)
 
     def test_auto_generated_use_date(self):
         voucher_type = create_voucher_type()
@@ -24,7 +28,7 @@ class VoucherFormTests(LoggedInWithWorkerTestCase):
         voucher_form = VoucherForm()
         form_data = {
             "status": VOUCHER_STATUS_USED,
-            "usage_partner": str(self.worker.id),
+            "usage_partner": str(self.voucher_partner.id),
             "voucher_type": voucher_type.id
         }
         for key, value in voucher_form.initial.items():
@@ -58,7 +62,7 @@ class VoucherFormTests(LoggedInWithWorkerTestCase):
     def test_valid_status(self):
         study_subject = create_study_subject()
         voucher = create_voucher(study_subject)
-        voucher.usage_partner = self.worker
+        voucher.usage_partner = self.voucher_partner
         voucher.save()
 
         voucher_form = VoucherForm(instance=voucher)
diff --git a/smash/web/tests/functions.py b/smash/web/tests/functions.py
index 8261bd6335145cc090f610467b3a7c6523eaeaef..b3855137660292a0c9726bff01709179fa6d35b8 100644
--- a/smash/web/tests/functions.py
+++ b/smash/web/tests/functions.py
@@ -4,12 +4,13 @@ import os
 
 from django.contrib.auth.models import User
 
+from web.models.worker_study_role import ROLE_CHOICES_DOCTOR
 from web.models import Location, AppointmentType, StudySubject, Worker, Visit, Appointment, ConfigurationItem, \
     Language, ContactAttempt, FlyingTeam, Availability, Subject, Study, StudyColumns, StudyNotificationParameters, \
-    VoucherType, VoucherTypePrice, Voucher
+    VoucherType, VoucherTypePrice, Voucher, WorkerStudyRole
 from web.models.constants import REDCAP_TOKEN_CONFIGURATION_TYPE, REDCAP_BASE_URL_CONFIGURATION_TYPE, \
     SEX_CHOICES_MALE, SUBJECT_TYPE_CHOICES_CONTROL, CONTACT_TYPES_PHONE, \
-    MONDAY_AS_DAY_OF_WEEK, COUNTRY_AFGHANISTAN_ID, VOUCHER_STATUS_NEW
+    MONDAY_AS_DAY_OF_WEEK, COUNTRY_AFGHANISTAN_ID, VOUCHER_STATUS_NEW, GLOBAL_STUDY_ID
 from web.redcap_connector import RedcapSubject
 from web.views.notifications import get_today_midnight_date
 
@@ -187,12 +188,16 @@ def create_worker(user=None, with_test_location=False):
     worker = Worker.objects.create(
         first_name='piotr',
         last_name="gawron",
-        email='jacob@bla',
+        email='jacob@bla.com',
         user=user,
+        specialization="spec",
+        unit="LCSB",
+        phone_number="0123456789"
     )
     if with_test_location:
         worker.locations = [get_test_location()]
         worker.save()
+    WorkerStudyRole.objects.create(worker=worker, study_id=GLOBAL_STUDY_ID, role=ROLE_CHOICES_DOCTOR)
     return worker
 
 
diff --git a/smash/web/tests/models/test_worker.py b/smash/web/tests/models/test_worker.py
index e43ae0bb4120e7c1e610336cb10380253d5f25f1..1b479467a673a15eb108e2ba61aaf519fde703f2 100644
--- a/smash/web/tests/models/test_worker.py
+++ b/smash/web/tests/models/test_worker.py
@@ -4,6 +4,9 @@ from django.contrib.auth.models import User, AnonymousUser
 from django.test import Client, TestCase
 
 from web.models import Holiday, Worker
+from web.models.worker import role_choices_by_worker_type, worker_type_by_worker
+from web.models.worker_study_role import WORKER_STAFF, ROLE_CHOICES_SECRETARY, ROLE_CHOICES_HEALTH_PARTNER, \
+    WORKER_HEALTH_PARTNER, ROLE_CHOICES_VOUCHER_PARTNER, WORKER_VOUCHER_PARTNER
 from web.tests.functions import create_worker
 from web.views.notifications import get_today_midnight_date
 
@@ -60,3 +63,31 @@ class WorkerModelTests(TestCase):
 
     def test_get_by_user_for_anonymous(self):
         self.assertIsNone(Worker.get_by_user(AnonymousUser()))
+
+    def test_role_choices_by_worker_type(self):
+        with self.assertRaises(Exception):
+            role_choices_by_worker_type("invalid arg")
+
+    def test_worker_type_by_worker_without_role(self):
+        self.assertEqual(WORKER_STAFF, worker_type_by_worker(Worker()))
+
+    def test_worker_type_by_worker_with_secretary_role(self):
+        worker = create_worker()
+        worker.roles.update(role=ROLE_CHOICES_SECRETARY)
+        self.assertEqual(WORKER_STAFF, worker_type_by_worker(worker))
+
+    def test_worker_type_by_worker_with_health_partner_role(self):
+        worker = create_worker()
+        worker.roles.update(role=ROLE_CHOICES_HEALTH_PARTNER)
+        self.assertEqual(WORKER_HEALTH_PARTNER, worker_type_by_worker(worker))
+
+    def test_worker_type_by_worker_with_voucher_partner_role(self):
+        worker = create_worker()
+        worker.roles.update(role=ROLE_CHOICES_VOUCHER_PARTNER)
+        self.assertEqual(WORKER_VOUCHER_PARTNER, worker_type_by_worker(worker))
+
+    def test_worker_type_by_worker_with_invalid_role(self):
+        worker = create_worker()
+        worker.roles.update(role="unk")
+        with self.assertRaises(Exception):
+            worker_type_by_worker(worker)
diff --git a/smash/web/tests/view/test_appointments.py b/smash/web/tests/view/test_appointments.py
index 9560cfa02a577b900b541addbf304c98e0506747..a1544f213bdcfcb70a699f4b9299c61faa5b069d 100644
--- a/smash/web/tests/view/test_appointments.py
+++ b/smash/web/tests/view/test_appointments.py
@@ -4,7 +4,7 @@ import logging
 from django.core.files.uploadedfile import SimpleUploadedFile
 from django.urls import reverse
 
-from web.forms import AppointmentEditForm, SubjectEditForm, StudySubjectEditForm
+from web.forms import SubjectEditForm, StudySubjectEditForm, AppointmentEditForm
 from web.models import Appointment, StudySubject, Visit
 from web.tests import LoggedInTestCase
 from web.tests.functions import create_study_subject, create_visit, create_appointment, create_worker, \
diff --git a/smash/web/tests/view/test_doctor.py b/smash/web/tests/view/test_worker.py
similarity index 51%
rename from smash/web/tests/view/test_doctor.py
rename to smash/web/tests/view/test_worker.py
index 5689a18676c0a8dd5b67e357a9302d1c58785304..ecf3d30329507a5a3f8acb668ed9488a35b65834 100644
--- a/smash/web/tests/view/test_doctor.py
+++ b/smash/web/tests/view/test_worker.py
@@ -2,77 +2,94 @@ import logging
 
 from django.urls import reverse
 
-from web.tests.functions import create_language, create_location, create_availability
-from web.forms import WorkerAddForm
-from web.tests import create_worker
+from web.forms import WorkerForm
 from web.models import Worker
+from web.models.worker_study_role import WORKER_STAFF, ROLE_CHOICES_DOCTOR
+from web.tests import create_worker
+from web.tests.functions import create_language, create_location, create_availability, format_form_field
 from .. import LoggedInTestCase
 
 logger = logging.getLogger(__name__)
 
 
-class DoctorViewTests(LoggedInTestCase):
+class WorkerViewTests(LoggedInTestCase):
     def test_render_workers_list_request(self):
         create_worker()
 
-        response = self.client.get(reverse('web.views.doctors'))
+        response = self.client.get(reverse('web.views.workers'))
         self.assertEqual(response.status_code, 200)
 
     def test_render_add_worker_request(self):
         create_worker()
 
-        response = self.client.get(reverse('web.views.doctor_add'))
+        response = self.client.get(reverse('web.views.worker_add', kwargs={'worker_type': WORKER_STAFF}))
         self.assertEqual(response.status_code, 200)
 
     def test_render_worker_added_request(self):
-
         language = create_language()
         location = create_location()
-        count = Worker.objects.all().count()
 
-        form = WorkerAddForm()
-        form_data = {}
-        for key, value in form.initial.items():
-            if value is not None:
-                form_data[key] = value
+        form_data = self.get_form_data(Worker())
         form_data["first_name"] = "John"
         form_data["last_name"] = "Doe"
         form_data["phone_number"] = "0123456789"
         form_data["unit"] = "TEST DEPARTMENT"
         form_data["email"] = "john.doe@unknown.domain.com"
-        form_data["role"] = Worker.ROLE_CHOICES_DOCTOR
         form_data["specialization"] = "tester"
         form_data["languages"] = [language.id]
         form_data["locations"] = [location.id]
+        form_data["role"] = ROLE_CHOICES_DOCTOR
 
-        response = self.client.post(reverse('web.views.doctor_add'), data=form_data)
+        response = self.client.post(reverse('web.views.worker_add', kwargs={'worker_type': WORKER_STAFF}),
+                                    data=form_data)
+        logger.debug(response.content)
 
         self.assertEqual(response.status_code, 302)
 
-        new_count = Worker.objects.all().count()
-        self.assertEqual(count + 1, new_count)
+        self.assertEqual(1, Worker.objects.all().count())
+
+    @staticmethod
+    def get_form_data(worker=None):
+        form = WorkerForm(instance=worker)
+        form_data = {}
+        for key, value in form.initial.items():
+            form_data[key] = format_form_field(value)
+        return form_data
 
     def test_render_edit_worker_request(self):
         worker = create_worker()
 
-        response = self.client.get(reverse('web.views.doctor_edit', args=[worker.id]))
+        form_data = self.get_form_data(worker)
+        form_data["last_name"] = "XYZ"
+        form_data["role"] = ROLE_CHOICES_DOCTOR
+
+        response = self.client.post(reverse('web.views.worker_edit', args=[worker.id]), data=form_data)
+        self.assertEqual(response.status_code, 302)
+
+        updated_worker = Worker.objects.get(id=worker.id)
+        self.assertEqual(updated_worker.last_name, form_data["last_name"])
+
+    def test_edit_worker(self):
+        worker = create_worker()
+
+        response = self.client.get(reverse('web.views.worker_edit', args=[worker.id]))
         self.assertEqual(response.status_code, 200)
 
     def test_render_add_availability_request(self):
         worker = create_worker()
 
-        response = self.client.get(reverse('views.doctor.doctor_availability_add', args=[worker.id]))
+        response = self.client.get(reverse('web.views.worker_availability_add', args=[worker.id]))
         self.assertEqual(response.status_code, 200)
 
     def test_render_edit_availability_request(self):
         worker = create_worker()
         availability = create_availability(worker)
 
-        response = self.client.get(reverse('web.views.doctor_availability_edit', args=[availability.id]))
+        response = self.client.get(reverse('web.views.worker_availability_edit', args=[availability.id]))
         self.assertEqual(response.status_code, 200)
 
     def test_render_add_holiday_request(self):
         worker = create_worker()
 
-        response = self.client.get(reverse('views.doctor.doctor_holiday_add', args=[worker.id]))
+        response = self.client.get(reverse('web.views.worker_holiday_add', args=[worker.id]))
         self.assertEqual(response.status_code, 200)
diff --git a/smash/web/urls.py b/smash/web/urls.py
index c58aa7bb6a3cebcf9310718f5c7042e1ca58e02f..f5da2cb56dd161f3a3f82f2e37d366d25ca9fef4 100644
--- a/smash/web/urls.py
+++ b/smash/web/urls.py
@@ -99,23 +99,24 @@ urlpatterns = [
     #     DOCTORS      #
     ####################
 
-    url(r'^doctors$', views.doctor.doctors, name='web.views.doctors'),
-    url(r'^doctors/add$', views.doctor.doctor_add, name='web.views.doctor_add'),
-    url(r'^doctors/edit/(?P<doctor_id>\d+)$', views.doctor.doctor_edit, name='web.views.doctor_edit'),
-    url(r'^doctors/disable/(?P<doctor_id>\d+)$', views.doctor.doctor_disable, name='web.views.doctor_disable'),
-    url(r'^doctors/(?P<doctor_id>\d+)/availability/add$', views.doctor.doctor_availability_add,
-        name='views.doctor.doctor_availability_add'),
-
-    url(r'^doctors/availability/(?P<availability_id>\d+)/delete$', views.doctor.doctor_availability_delete,
-        name='web.views.doctor_availability_delete'),
-    url(r'^doctors/availability/(?P<availability_id>\d+)/edit', views.doctor.doctor_availability_edit,
-        name='web.views.doctor_availability_edit'),
-
-    url(r'^doctors/(?P<doctor_id>\d+)/holiday/add$', views.doctor.doctor_holiday_add,
-        name='views.doctor.doctor_holiday_add'),
-
-    url(r'^doctors/holiday/(?P<holiday_id>\d+)/delete$', views.doctor.doctor_holiday_delete,
-        name='web.views.doctor_holiday_delete'),
+    url(r'^doctors/$', views.worker.worker_list, name='web.views.workers'),
+    url(r'^doctors/(?P<worker_type>[A-z]+)$', views.worker.worker_list, name='web.views.workers'),
+    url(r'^doctors/add/(?P<worker_type>[A-z]+)$', views.worker.worker_add, name='web.views.worker_add'),
+    url(r'^doctors/edit/(?P<worker_id>\d+)$', views.worker.worker_edit, name='web.views.worker_edit'),
+    url(r'^doctors/disable/(?P<doctor_id>\d+)$', views.worker.worker_disable, name='web.views.worker_disable'),
+
+    url(r'^doctors/(?P<doctor_id>\d+)/availability/add$', views.worker.worker_availability_add,
+        name='web.views.worker_availability_add'),
+    url(r'^doctors/availability/(?P<availability_id>\d+)/delete$', views.worker.worker_availability_delete,
+        name='web.views.worker_availability_delete'),
+    url(r'^doctors/availability/(?P<availability_id>\d+)/edit', views.worker.worker_availability_edit,
+        name='web.views.worker_availability_edit'),
+
+    url(r'^doctors/(?P<doctor_id>\d+)/holiday/add$', views.worker.worker_holiday_add,
+        name='web.views.worker_holiday_add'),
+
+    url(r'^doctors/holiday/(?P<holiday_id>\d+)/delete$', views.worker.worker_holiday_delete,
+        name='web.views.worker_holiday_delete'),
 
     ####################
     #    EQUIPMENT     #
diff --git a/smash/web/views/__init__.py b/smash/web/views/__init__.py
index fedbe5fd8b6300d36166e6e9ba058174553a0352..6ca5ef439294203655a29509a9fc29cb49c64e8f 100644
--- a/smash/web/views/__init__.py
+++ b/smash/web/views/__init__.py
@@ -67,7 +67,7 @@ class WrappedView(ContextMixin):
 import auth
 import appointment
 import visit
-import doctor
+import worker
 import subject
 import equipment
 import flying_teams
diff --git a/smash/web/views/appointment.py b/smash/web/views/appointment.py
index fac01b5a1d1aabe6537fb641e13612734b3a6e76..d45f67f8c6067ac2185519b3284e5f6ffd0c2b76 100644
--- a/smash/web/views/appointment.py
+++ b/smash/web/views/appointment.py
@@ -9,7 +9,7 @@ from django.shortcuts import get_object_or_404, redirect
 from web.models.appointment_list import APPOINTMENT_LIST_APPROACHING, APPOINTMENT_LIST_GENERIC, \
     APPOINTMENT_LIST_UNFINISHED
 from . import wrap_response
-from ..forms import AppointmentDetailForm, AppointmentAddForm, AppointmentEditForm, SubjectEditForm, \
+from web.forms import AppointmentDetailForm, AppointmentEditForm, AppointmentAddForm, SubjectEditForm, \
     StudySubjectEditForm
 from ..models import Appointment, StudySubject, MailTemplate
 
diff --git a/smash/web/views/contact_attempt.py b/smash/web/views/contact_attempt.py
index 6694bc41836623bef0041fe6c7861ee2e4a4c7bc..40d66ae2c454bfe265aa021f31e8041e1f93de16 100644
--- a/smash/web/views/contact_attempt.py
+++ b/smash/web/views/contact_attempt.py
@@ -1,14 +1,14 @@
 from django.shortcuts import redirect, get_object_or_404
 
+from web.forms import ContactAttemptAddForm, ContactAttemptEditForm
+from web.models import StudySubject, ContactAttempt
 from . import wrap_response
-from ..forms import ContactAttemptForm, ContactAttemptEditForm
-from ..models import StudySubject, ContactAttempt
 
 
 def contact_add(request, subject_id):
     subject = get_object_or_404(StudySubject, id=subject_id)
     if request.method == 'POST':
-        form = ContactAttemptForm(request.POST, user=request.user, subject=subject)
+        form = ContactAttemptAddForm(request.POST, user=request.user, subject=subject)
         form.instance.subject_id = subject_id
         if form.is_valid():
             form.save()
@@ -17,7 +17,7 @@ def contact_add(request, subject_id):
             else:
                 return redirect('web.views.subject_edit', id=subject_id)
     else:
-        form = ContactAttemptForm(user=request.user, subject=subject)
+        form = ContactAttemptAddForm(user=request.user, subject=subject)
 
     return wrap_response(request, 'contact_attempt/add.html',
                          {'form': form, 'subject_id': subject_id})
diff --git a/smash/web/views/doctor.py b/smash/web/views/worker.py
similarity index 55%
rename from smash/web/views/doctor.py
rename to smash/web/views/worker.py
index d6738333ac2225cebac3be65db76e3e85448a403..12914af5ca91250b897ce1824437b780d213aa95 100644
--- a/smash/web/views/doctor.py
+++ b/smash/web/views/worker.py
@@ -1,79 +1,86 @@
 # coding=utf-8
+import logging
+
+from django.contrib.auth.decorators import login_required
 from django.shortcuts import redirect, get_object_or_404
 
+from web.forms import AvailabilityAddForm, AvailabilityEditForm, HolidayAddForm
+from web.forms import WorkerForm
+from web.models import Worker, Availability, Holiday
+from web.models.constants import WEEKDAY_CHOICES, GLOBAL_STUDY_ID
+from web.models.worker import worker_type_by_worker
+from web.models.worker_study_role import WORKER_STAFF
 from . import wrap_response
-from ..forms import WorkerAddForm, WorkerEditForm, AvailabilityAddForm, AvailabilityEditForm, HolidayAddForm
-from ..models import Worker, Availability, Holiday
-from ..models.constants import WEEKDAY_CHOICES
+
+logger = logging.getLogger(__name__)
 
 
-def doctors(request):
-    doctors_list = Worker.objects.order_by('-last_name')
+def worker_list(request, worker_type=WORKER_STAFF):
+    doctors_list = Worker.get_workers_by_worker_type(worker_type, study_id=GLOBAL_STUDY_ID, ).order_by('-last_name')
     context = {
-        'doctors_list': doctors_list
+        'doctors_list': doctors_list,
+        'worker_type': worker_type
     }
 
     return wrap_response(request, "doctors/index.html", context)
 
 
-def doctor_add(request):
+def worker_add(request, worker_type):
     if request.method == 'POST':
-        form = WorkerAddForm(request.POST, request.FILES)
+        form = WorkerForm(request.POST, request.FILES, worker_type=worker_type)
         if form.is_valid():
             form.save()
-            return redirect('web.views.doctors')
+            return redirect('web.views.workers')
     else:
-        form = WorkerAddForm()
+        form = WorkerForm(worker_type=worker_type)
 
     return wrap_response(request, 'doctors/add.html', {'form': form})
 
 
-def doctor_edit(request, doctor_id):
-    the_doctor = get_object_or_404(Worker, id=doctor_id)
+def worker_edit(request, worker_id):
+    worker = get_object_or_404(Worker, id=worker_id)
     if request.method == 'POST':
-        form = WorkerEditForm(request.POST, request.FILES, instance=the_doctor)
+        form = WorkerForm(request.POST, request.FILES, instance=worker, worker_type=worker_type_by_worker(worker))
         if form.is_valid():
             form.save()
-            return redirect('web.views.doctors')
+            return redirect('web.views.workers')
     else:
-        form = WorkerEditForm(instance=the_doctor)
-    availabilities = Availability.objects.filter(person=doctor_id).order_by('day_number', 'available_from')
-    holidays = Holiday.objects.filter(person=doctor_id).order_by('-datetime_start')
+        form = WorkerForm(instance=worker)
+    availabilities = Availability.objects.filter(person=worker_id).order_by('day_number', 'available_from')
+    holidays = Holiday.objects.filter(person=worker_id).order_by('-datetime_start')
     return wrap_response(request, 'doctors/edit.html',
                          {
                              'form': form,
                              'availabilities': availabilities,
                              'holidays': holidays,
-                             'doctor_id': doctor_id,
+                             'doctor_id': worker_id,
                              'weekdays': WEEKDAY_CHOICES
                          })
 
 
-def doctor_disable(request, doctor_id):
+def worker_disable(request, doctor_id):
     the_doctor = get_object_or_404(Worker, id=doctor_id)
     the_doctor.disable()
-    return doctors(request)
+    return worker_list(request)
 
 
-def doctor_availability_delete(request, availability_id):
+@login_required
+def worker_availability_delete(request, availability_id):
     availability = Availability.objects.filter(id=availability_id)
     doctor_id = availability[0].person.id
     availability.delete()
-    return redirect(doctor_edit, doctor_id=doctor_id)
+    return redirect(worker_edit, doctor_id=doctor_id)
 
 
-def doctor_availability_add(request, doctor_id):
-    doctors = Worker.objects.filter(id=doctor_id)
-    doctor = None
-    if len(doctors) > 0:
-        doctor = doctors[0]
+def worker_availability_add(request, doctor_id):
+    worker = get_object_or_404(Worker, id=doctor_id)
     if request.method == 'POST':
         form = AvailabilityAddForm(request.POST, request.FILES)
         if form.is_valid():
             form.save()
-            return redirect(doctor_edit, doctor_id=doctor_id)
+            return redirect(worker_edit, doctor_id=doctor_id)
     else:
-        form = AvailabilityAddForm(initial={'person': doctor})
+        form = AvailabilityAddForm(initial={'person': worker})
     return wrap_response(request, 'doctors/add_availability.html',
                          {
                              'form': form,
@@ -81,13 +88,13 @@ def doctor_availability_add(request, doctor_id):
                          })
 
 
-def doctor_availability_edit(request, availability_id):
+def worker_availability_edit(request, availability_id):
     availability = get_object_or_404(Availability, id=availability_id)
     if request.method == 'POST':
         form = AvailabilityEditForm(request.POST, request.FILES, instance=availability)
         if form.is_valid():
             form.save()
-            return redirect(doctor_edit, doctor_id=availability.person_id)
+            return redirect(worker_edit, doctor_id=availability.person_id)
     else:
         form = AvailabilityEditForm(instance=availability)
     return wrap_response(request, 'doctors/edit_availability.html',
@@ -98,14 +105,15 @@ def doctor_availability_edit(request, availability_id):
                          })
 
 
-def doctor_holiday_delete(request, holiday_id):
+@login_required
+def worker_holiday_delete(request, holiday_id):
     holiday = Holiday.objects.filter(id=holiday_id)
     doctor_id = holiday[0].person.id
     holiday.delete()
-    return redirect(doctor_edit, doctor_id=doctor_id)
+    return redirect(worker_edit, doctor_id=doctor_id)
 
 
-def doctor_holiday_add(request, doctor_id):
+def worker_holiday_add(request, doctor_id):
     doctors = Worker.objects.filter(id=doctor_id)
     doctor = None
     if len(doctors) > 0:
@@ -114,7 +122,7 @@ def doctor_holiday_add(request, doctor_id):
         form = HolidayAddForm(request.POST, request.FILES)
         if form.is_valid():
             form.save()
-            return redirect(doctor_edit, doctor_id=doctor_id)
+            return redirect(worker_edit, doctor_id=doctor_id)
     else:
         form = HolidayAddForm(initial={'person': doctor})
     return wrap_response(request, 'doctors/add_holiday.html',