diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 8cfd55f3ec6c0d9daf2a9017bd6295d33d66b10d..eec2748df839b102259fb156265a5ae78a83c3a0 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -19,4 +19,4 @@ test:
          - cd smash
          - python manage.py makemigrations web && python manage.py migrate
          - coverage run --source web manage.py test
-         - coverage report -m --omit="*/test*,*/migrations*"
+         - coverage report -m --omit="*/test*,*/migrations*,*debug_utils*"
diff --git a/requirements.txt b/requirements.txt
index 95ab826f6bcb399e5f0f90d81945eff3cdbc584c..01f45824f0cbf1d4f885b222807a543dcaf2de59 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,3 +1,6 @@
+pandas==0.23.4
+numpy==1.15.2
+matplotlib==2.2.3
 Django==1.11.5
 gunicorn==19.6.0
 Pillow==3.4.2
diff --git a/smash/web/api_urls.py b/smash/web/api_urls.py
index 372aa370c6f24960f3122b1c18b24e8494fac9a0..61777145a4a8dac58738ad3164d1cb2e0f4d85f9 100644
--- a/smash/web/api_urls.py
+++ b/smash/web/api_urls.py
@@ -67,6 +67,9 @@ urlpatterns = [
     url(r'^availabilities/(?P<date>\d{4}-\d{2}-\d{2})/$', daily_planning.availabilities, name='web.api.availabilities'),
     url(r'^events_persist$', daily_planning.events_persist, name='web.api.events_persist'),
 
+    #worker availability
+    url(r'^worker_availability/$', worker.get_worker_availability, name='web.api.get_worker_availability'),
+
     # worker data
     url(r'^redcap/missing_subjects/(?P<missing_subject_id>\d+):ignore$', redcap.ignore_missing_subject,
         name='web.api.redcap.ignore_missing_subject'),
diff --git a/smash/web/api_views/daily_planning.py b/smash/web/api_views/daily_planning.py
index ec08fdcd5b6b83a46694dfe13e6aeb96e667ca62..773131ec056af9b6b55c919d2bcdcdb44e13c090 100644
--- a/smash/web/api_views/daily_planning.py
+++ b/smash/web/api_views/daily_planning.py
@@ -57,6 +57,7 @@ def get_holidays(worker, date):
             'link_when': start_date,
             'link_who': worker.id,
             'link_end': end_date,
+            'kind': holiday.kind
         }
         result.append(event)
 
@@ -246,8 +247,9 @@ def events(request, date):
             subject = {
                 'name': unicode(appointment_subject),
                 'id': appointment_subject.id,
+                'appointment_id': appointment.id,
                 'color': RANDOM_COLORS[i],
-                'start': appointment.datetime_when.replace(tzinfo=None).strftime("%H:%M:00"),
+                'start': appointment.datetime_when.replace(tzinfo=None).strftime("%H:%M"),
                 # this indicates only location of the first appointment
                 # (there is small chance to have two appointments in two different places at the same day)
                 'location': str(appointment.location),
diff --git a/smash/web/api_views/worker.py b/smash/web/api_views/worker.py
index 39eb016eead7bbde9c4478276c82f27e39fd50cf..836fa83d720fdcee65b532d1727f2621682d5608 100644
--- a/smash/web/api_views/worker.py
+++ b/smash/web/api_views/worker.py
@@ -1,12 +1,15 @@
 import datetime
-
-from django.http import JsonResponse
+import logging
+import json
+from django.http import JsonResponse, HttpResponse
 from django.utils import timezone
 
+from django.shortcuts import get_object_or_404
 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
 
+logger = logging.getLogger(__name__)
 
 def specializations(request):
     workers = Worker.objects.filter(specialization__isnull=False).values_list('specialization').distinct()
@@ -21,14 +24,18 @@ def units(request):
         "units": [x[0] for x in workers]
     })
 
-
 def workers_for_daily_planning(request):
+    start_date = request.GET.get('start_date')
     workers = get_workers_for_daily_planning(request)
     workers_list_for_json = []
+    if start_date is not None:
+        today = timezone.now()
+        start_date=datetime.datetime.strptime(start_date, '%Y-%m-%d').replace(tzinfo=today.tzinfo)
     for worker in workers:
         role = unicode(worker.roles.filter(study_id=GLOBAL_STUDY_ID)[0].role)
         worker_dict_for_json = {
             'id': worker.id,
+            'availability': worker.availability_percentage(start_date=start_date),
             'title': u"{} ({})".format(unicode(worker), role[:1].upper()),
             'role': role
         }
@@ -86,3 +93,31 @@ def serialize_worker(worker):
         "id": worker.id,
     }
     return result
+
+def get_worker_availability(request):
+    start_str_date = request.GET.get("start_date")
+    end_str_date = request.GET.get("end_date")
+    worker_id = request.GET.get("worker_id")
+    
+    if start_str_date is None or worker_id is None:
+        context = {
+            'status': '400', 'reason': 'Either start_date, worker_id or both are invalid.' 
+        }
+        response = HttpResponse(json.dumps(context), content_type='application/json')
+        response.status_code = 400
+        return response
+
+    start_date = datetime.datetime.strptime(start_str_date, "%Y-%m-%d-%H-%M").replace(tzinfo=timezone.now().tzinfo)
+    if end_str_date is None or end_str_date == start_str_date:
+        start_date = start_date.replace(hour=0, minute=0, second=0)
+        end_date = start_date + datetime.timedelta(days=1)
+    else:
+        end_date = datetime.datetime.strptime(end_str_date, "%Y-%m-%d-%H-%M").replace(tzinfo=timezone.now().tzinfo)
+    worker = get_object_or_404(Worker, id=int(worker_id))
+
+    result = {
+        'start_date': start_date,
+        'end_date': end_date, 
+        'availability': round(worker.availability_percentage(start_date=start_date, end_date=end_date), 0)
+    }
+    return JsonResponse(result)
\ No newline at end of file
diff --git a/smash/web/debug_utils.py b/smash/web/debug_utils.py
new file mode 100644
index 0000000000000000000000000000000000000000..fa04ebe448725534d015e406ff436b6e275f923b
--- /dev/null
+++ b/smash/web/debug_utils.py
@@ -0,0 +1,19 @@
+# coding=utf-8
+import time
+
+def timeit(method):
+    '''
+    Debug decorator to measure the execution time of some method or function
+    '''
+    def timed(*args, **kw):
+        ts = time.time()
+        result = method(*args, **kw)
+        te = time.time()
+        if 'log_time' in kw:
+            name = kw.get('log_name', method.__name__.upper())
+            kw['log_time'][name] = int((te - ts) * 1000)
+        else:
+            print '%r  %2.2f ms' % \
+                  (method.__name__, (te - ts) * 1000)
+        return result
+    return timed
\ No newline at end of file
diff --git a/smash/web/forms/appointment_form.py b/smash/web/forms/appointment_form.py
index 83b40597bc5d3ad21a7b5927e5a5c73e59004ff1..a832eb19da9f204ef55fe961d65e81bd0f5dad5b 100644
--- a/smash/web/forms/appointment_form.py
+++ b/smash/web/forms/appointment_form.py
@@ -115,6 +115,10 @@ class AppointmentAddForm(AppointmentForm):
                                                                              widget=forms.CheckboxSelectMultiple,
                                                                              queryset=AppointmentType.objects.all(),
                                                                              )
+        fields['worker_assigned'].widget.attrs = {'class': 'search_worker_availability'}
+        fields['datetime_when'].widget.attrs = {'class': 'start_date'}
+        fields['length'].widget.attrs = {'class': 'appointment_duration'}
+
         self.fields = fields
         self.fields['location'].queryset = get_filter_locations(self.user)
 
diff --git a/smash/web/forms/forms.py b/smash/web/forms/forms.py
index b426058577ffc456434243d69c8e61e94adcf8ac..3106fba657d935031fcf148a5cbe6c253dc6c9d2 100644
--- a/smash/web/forms/forms.py
+++ b/smash/web/forms/forms.py
@@ -123,6 +123,10 @@ class StatisticsForm(Form):
 
 
 class AvailabilityAddForm(ModelForm):
+    def __init__(self, *args, **kwargs):
+        super(AvailabilityAddForm, self).__init__(*args, **kwargs)
+        self.fields['person'].widget.attrs['readonly'] = True
+    
     available_from = forms.TimeField(label="Available from",
                                      widget=forms.TimeInput(TIMEPICKER_DATE_ATTRS),
                                      initial="8:00",
@@ -204,6 +208,10 @@ class FlyingTeamEditForm(ModelForm):
 
 
 class HolidayAddForm(ModelForm):
+    def __init__(self, *args, **kwargs):
+        super(HolidayAddForm, self).__init__(*args, **kwargs)
+        self.fields['person'].widget.attrs['readonly'] = True
+
     datetime_start = forms.DateTimeField(widget=forms.DateTimeInput(DATETIMEPICKER_DATE_ATTRS),
                                          initial=datetime.datetime.now().replace(hour=8, minute=0),
                                          )
diff --git a/smash/web/migrations/0119_auto_20181002_0908.py b/smash/web/migrations/0119_auto_20181002_0908.py
new file mode 100644
index 0000000000000000000000000000000000000000..3f3a9a06ccbba72db9a92a1f4a682fbcf19318c0
--- /dev/null
+++ b/smash/web/migrations/0119_auto_20181002_0908.py
@@ -0,0 +1,20 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.5 on 2018-10-02 09:08
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('web', '0118_voucher_activity_type'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='workerstudyrole',
+            name='role',
+            field=models.CharField(choices=[(b'DOCTOR', b'Doctor'), (b'NURSE', b'Nurse'), (b'PSYCHOLOGIST', b'Psychologist'), (b'TECHNICIAN', b'Technician'), (b'SECRETARY', b'Secretary'), (b'PROJECT MANAGER', b'Project Manager')], max_length=20, verbose_name=b'Role'),
+        ),
+    ]
diff --git a/smash/web/migrations/0119_auto_20181015_1324.py b/smash/web/migrations/0119_auto_20181015_1324.py
new file mode 100644
index 0000000000000000000000000000000000000000..3f4d4840a0ac7dbcf05d93adf550587cb1412581
--- /dev/null
+++ b/smash/web/migrations/0119_auto_20181015_1324.py
@@ -0,0 +1,25 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.5 on 2018-10-15 13:24
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('web', '0118_voucher_activity_type'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='studyvisitlist',
+            name='type',
+            field=models.CharField(choices=[(b'UNFINISHED', b'Unfinished visits'), (b'APPROACHING_WITHOUT_APPOINTMENTS', b'Approaching visits'), (b'APPROACHING_FOR_MAIL_CONTACT', b'Post mail for approaching visits'), (b'GENERIC', b'Generic visit list'), (b'MISSING_APPOINTMENTS', b'Visits with missing appointments'), (b'EXCEEDED_TIME', b'Exceeded visit time')], max_length=50, verbose_name=b'Type of list'),
+        ),
+        migrations.AlterField(
+            model_name='workerstudyrole',
+            name='role',
+            field=models.CharField(choices=[(b'DOCTOR', b'Doctor'), (b'NURSE', b'Nurse'), (b'PSYCHOLOGIST', b'Psychologist'), (b'TECHNICIAN', b'Technician'), (b'SECRETARY', b'Secretary'), (b'PROJECT MANAGER', b'Project Manager')], max_length=20, verbose_name=b'Role'),
+        ),
+    ]
diff --git a/smash/web/migrations/0120_holiday_kind.py b/smash/web/migrations/0120_holiday_kind.py
new file mode 100644
index 0000000000000000000000000000000000000000..688d8f04cbc5fc25594949c5d8d436c4bf58cc86
--- /dev/null
+++ b/smash/web/migrations/0120_holiday_kind.py
@@ -0,0 +1,20 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.5 on 2018-10-03 09:11
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('web', '0119_auto_20181002_0908'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='holiday',
+            name='kind',
+            field=models.CharField(choices=[(b'H', b'Holiday'), (b'X', b'Extra Availability')], default=b'H', max_length=1),
+        ),
+    ]
diff --git a/smash/web/migrations/0121_auto_20181003_1256.py b/smash/web/migrations/0121_auto_20181003_1256.py
new file mode 100644
index 0000000000000000000000000000000000000000..a350af1604c22d5f97a0f6290a56ce2920c33155
--- /dev/null
+++ b/smash/web/migrations/0121_auto_20181003_1256.py
@@ -0,0 +1,20 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.5 on 2018-10-03 12:56
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('web', '0120_holiday_kind'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='holiday',
+            name='kind',
+            field=models.CharField(choices=[(b'H', b'Holiday'), (b'X', b'Extra Availability')], default=b'H', help_text=b'Defines the kind of availability. Either Holiday or Extra Availability.', max_length=1),
+        ),
+    ]
diff --git a/smash/web/migrations/0122_remove_worker_appointments.py b/smash/web/migrations/0122_remove_worker_appointments.py
new file mode 100644
index 0000000000000000000000000000000000000000..b2df6305c497a1a49f0ac64d872f67c3c9d75d29
--- /dev/null
+++ b/smash/web/migrations/0122_remove_worker_appointments.py
@@ -0,0 +1,19 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.5 on 2018-10-10 12:29
+from __future__ import unicode_literals
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('web', '0121_auto_20181003_1256'),
+    ]
+
+    operations = [
+        migrations.RemoveField(
+            model_name='worker',
+            name='appointments',
+        ),
+    ]
diff --git a/smash/web/migrations/0123_merge_20181017_1532.py b/smash/web/migrations/0123_merge_20181017_1532.py
new file mode 100644
index 0000000000000000000000000000000000000000..a805cf53f1733f6e230ff0e1b5012f08cb1dc0b2
--- /dev/null
+++ b/smash/web/migrations/0123_merge_20181017_1532.py
@@ -0,0 +1,16 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.5 on 2018-10-17 15:32
+from __future__ import unicode_literals
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('web', '0119_auto_20181015_1324'),
+        ('web', '0122_remove_worker_appointments'),
+    ]
+
+    operations = [
+    ]
diff --git a/smash/web/migrations/0124_auto_20181017_1532.py b/smash/web/migrations/0124_auto_20181017_1532.py
new file mode 100644
index 0000000000000000000000000000000000000000..8ebc0e3b07022640ba756f344dc72f499b3ce28a
--- /dev/null
+++ b/smash/web/migrations/0124_auto_20181017_1532.py
@@ -0,0 +1,20 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.5 on 2018-10-17 15:32
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('web', '0123_merge_20181017_1532'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='studyvisitlist',
+            name='type',
+            field=models.CharField(choices=[(b'UNFINISHED', b'unfinished visits'), (b'APPROACHING_WITHOUT_APPOINTMENTS', b'approaching visits'), (b'APPROACHING_FOR_MAIL_CONTACT', b'post mail for approaching visits'), (b'GENERIC', b'Generic visit list'), (b'MISSING_APPOINTMENTS', b'visits with missing appointments'), (b'EXCEEDED_TIME', b'exceeded visit time')], max_length=50, verbose_name=b'Type of list'),
+        ),
+    ]
diff --git a/smash/web/models/constants.py b/smash/web/models/constants.py
index ad7354a0bda27a3c369369e0425657fa6499e708..3257a992b3dae412e271019a38e5342855acae0e 100644
--- a/smash/web/models/constants.py
+++ b/smash/web/models/constants.py
@@ -78,6 +78,14 @@ WEEKDAY_CHOICES = (
     (SUNDAY_AS_DAY_OF_WEEK, 'SUNDAY'),
 )
 
+AVAILABILITY_HOLIDAY = 'H'
+AVAILABILITY_EXTRA = 'X'
+
+AVAILABILITY_CHOICES = (
+    (AVAILABILITY_HOLIDAY, 'Holiday'),
+    (AVAILABILITY_EXTRA, 'Extra Availability'),
+)
+
 REDCAP_TOKEN_CONFIGURATION_TYPE = "REDCAP_TOKEN_CONFIGURATION_TYPE"
 REDCAP_BASE_URL_CONFIGURATION_TYPE = "REDCAP_BASE_URL_CONFIGURATION_TYPE"
 
diff --git a/smash/web/models/holiday.py b/smash/web/models/holiday.py
index 01cceaeadf3c442b6f6bb51874c47e682aae1072..927daa54340fd643e7ddd81a8f79e701238dbd7e 100644
--- a/smash/web/models/holiday.py
+++ b/smash/web/models/holiday.py
@@ -1,6 +1,7 @@
 # coding=utf-8
 from django.db import models
 
+from constants import AVAILABILITY_CHOICES, AVAILABILITY_HOLIDAY
 
 class Holiday(models.Model):
     class Meta:
@@ -21,6 +22,8 @@ class Holiday(models.Model):
                             verbose_name='Comments'
                             )
 
+    kind = models.CharField(max_length=1, choices=AVAILABILITY_CHOICES, default=AVAILABILITY_HOLIDAY, help_text='Defines the kind of availability. Either Holiday or Extra Availability.')
+
     def __str__(self):
         return "%s %s" % (self.person.first_name, self.person.last_name)
 
diff --git a/smash/web/models/worker.py b/smash/web/models/worker.py
index 86e2304dd544cadf224bec751e49b62f874301e6..85037ed18446e0149e3e8ef8d417eb666cec6ab2 100644
--- a/smash/web/models/worker.py
+++ b/smash/web/models/worker.py
@@ -2,13 +2,23 @@
 import datetime
 import logging
 
+from web.utils import get_today_midnight_date
+
 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.constants import GLOBAL_STUDY_ID, COUNTRY_OTHER_ID, AVAILABILITY_HOLIDAY, AVAILABILITY_EXTRA
 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, ROLE_CHOICES
 
+from web.utils import get_weekdays_in_period
+from web.officeAvailability import OfficeAvailability
+from django.db.models import Q
+from web.models.holiday import Holiday
+from web.models.availability import Availability
+from web.models.appointment import Appointment
+from web.models.appointment_type_link import AppointmentTypeLink
+
 logger = logging.getLogger(__name__)
 
 
@@ -61,9 +71,6 @@ class Worker(models.Model):
                                        verbose_name='Locations',
                                        blank=True
                                        )
-    appointments = models.ManyToManyField('web.Appointment', blank=True,
-                                          verbose_name='Appointments'
-                                          )
     user = models.OneToOneField(User, blank=True, null=True,
                                 verbose_name='Username'
                                 )
@@ -141,7 +148,8 @@ class Worker(models.Model):
 
     def is_on_leave(self):
         if len(self.holiday_set.filter(datetime_end__gt=datetime.datetime.now(),
-                                       datetime_start__lt=datetime.datetime.now())):
+                                       datetime_start__lt=datetime.datetime.now(),
+                                        kind=AVAILABILITY_HOLIDAY)):
             return True
         return False
 
@@ -161,6 +169,48 @@ class Worker(models.Model):
         else:
             return False
 
+    def is_available(self, start_date=None, end_date=None):
+        self.availability_percentage(start_date=start_date, end_date=end_date) > 50.0
+
+    def availability_percentage(self, start_date=None, end_date=None):
+        '''
+            start_date: defaults to None and then is set to today's midnight date 
+            end_date: defaults to None and then is set to today's midnight date + 24 hours
+        '''
+        today_midnight = get_today_midnight_date()
+
+        if start_date is None:
+            start_date = today_midnight
+        if end_date is None:
+            start_date = start_date.replace(hour=0, minute=0, second=0)
+            end_date = start_date + datetime.timedelta(days=1)
+
+        office_availability = OfficeAvailability('{} {}'.format(self.first_name, self.last_name), start=start_date, end=end_date)
+
+        #Appointments
+        subject_appointments = AppointmentTypeLink.objects.filter(worker=self.id, date_when__gte=start_date, date_when__lte=end_date)
+        general_appointments = Appointment.objects.filter(worker_assigned=self.id, datetime_when__gte=start_date, datetime_when__lte=end_date)
+
+        #Holidays and extra availabilities. 
+        holidays_and_extra_availabilities = self.holiday_set.filter(datetime_start__gte=start_date, datetime_end__lt=end_date).order_by('-datetime_start')
+
+        #Availability 
+        weekdays = get_weekdays_in_period(start_date, end_date)
+        weekdayQ = Q() #create a filter for each weekday in the selected period
+        for weekday in weekdays:
+            weekdayQ = weekdayQ | Q(day_number=weekday)
+        availabilities = self.availability_set.filter(person=self.id).filter(weekdayQ).order_by('day_number', 'available_from')
+
+        things = []
+        things.extend(availabilities)
+        things.extend(holidays_and_extra_availabilities)
+        things.extend(subject_appointments)
+        things.extend(general_appointments)
+        for thing in things:
+            office_availability.consider_this(thing, only_working_hours=True)
+
+        return office_availability.get_availability_percentage(only_working_hours=True)
+
     @property
     def role(self):
         roles = self.roles.filter(study=GLOBAL_STUDY_ID)
diff --git a/smash/web/officeAvailability.py b/smash/web/officeAvailability.py
new file mode 100644
index 0000000000000000000000000000000000000000..1ee732561d60b4351b67a9e4539d6622e3fbb167
--- /dev/null
+++ b/smash/web/officeAvailability.py
@@ -0,0 +1,225 @@
+# coding=utf-8
+import datetime
+from datetime import timedelta
+import logging
+import pandas as pd
+from web.utils import get_today_midnight_date
+from web.models.holiday import Holiday
+from web.models.availability import Availability
+from web.models.appointment import Appointment
+from web.models.appointment_type_link import AppointmentTypeLink
+from web.models.constants import AVAILABILITY_EXTRA, AVAILABILITY_HOLIDAY
+
+logger = logging.getLogger(__name__)
+
+#only for plot method
+import matplotlib
+matplotlib.use('Agg')
+import matplotlib.pyplot as plt
+
+class OfficeAvailability(object):
+	'''
+		start: datetime-like indicating when the range starts. If none, then today midnight
+		end: datetime-like indicating when the range ends. If none, then tomorrow midnight
+		office_start: when the office hours begin
+		office_end: when the office hours finish 
+		minimum_slot: frequency of the pandas series. T stands of minutes. Docs: https://pandas.pydata.org/pandas-docs/stable/generated/pandas.date_range.html
+	'''
+	def __init__(self, name, start=None, end=None, office_start='8:00', office_end='18:00', minimum_slot='1T'):
+		today_midnight = get_today_midnight_date()
+		tomorrow_midnight = today_midnight + datetime.timedelta(days=1)
+
+		if start is None:
+			self.start = today_midnight
+		else:
+			self.start = start
+
+		if end is None:
+			self.end = tomorrow_midnight
+		else:
+			self.end = end
+
+		self.name = name
+		self.office_start = office_start
+		self.office_end   = office_end
+		self.minimum_slot = minimum_slot
+		self.range = pd.date_range(start=self.start, end=self.end, freq=self.minimum_slot)
+		logger.debug('Min index: {}. Max index: {}'.format(self.start, self.end))
+		self.availability = pd.Series(index=self.range, data=0) # initialize range at 0
+	
+	def _get_duration(self):
+		'''
+		Private method. Returns the differ
+		'''
+		return self.availability.index[-1] - self.availability.index[0]
+
+	def add_availability(self, range, only_working_hours=False):
+		'''
+		Receives a pandas date_range `pd.date_range` object.
+		Sets the availability to one for the specific interval of the provided range.
+		'''
+		range = range.round(self.minimum_slot)
+		if only_working_hours:
+			range = range.to_series().between_time(self.office_start, self.office_end).index
+		self.availability[range] = 1
+
+	def remove_availability(self, range, only_working_hours=False):
+		'''
+		Receives a pandas date_range `pd.date_range` object.
+		Sets the availability to zero for the specific interval of the provided range.
+		'''
+		range = range.round(self.minimum_slot)
+		if only_working_hours:
+			range = range.to_series().between_time(self.office_start, self.office_end).index
+		self.availability[range] = 0
+
+	def consider_this(self, appointment_availability_or_holiday, only_working_hours=False):
+		'''
+			:appointment_availability_or_holiday can be an object from the following classes: Availability, Holiday, Appointment, AppointmentTypeLink.
+			:only_working_hours if true, only consider the defined working hours
+
+			Availability repeat every week.
+			Availability always refers to a moment in which the worker should be working. Never the opposite.
+			
+			Holiday has higher preference because it refers to extraordinary events like extra availability or lack of availability.
+			Holiday modifies the status of Availability for specific periods of time.
+
+			Only_working_hours: If true changed are limited to the provided working hours.
+
+			Known Issues: If the range to be added extends beyond the limits of the given time series range, the call to self.availability[portion.index] = set_to will fail.
+			It fails because there are keys missing within the time series of the object.
+
+			Two solutions are possible:
+			- First, limit the time periods of the ranges to be considered to the object time space. (current solution)
+			- Second, extend the object time space.
+
+			Notwithstanding, this issue shouldn't exist because in preivous steps we should receive the availabilities queried to the limits of this objects time space.
+			First proposal should be the solution to consider.
+		'''
+		if isinstance(appointment_availability_or_holiday, Availability):
+			start   = appointment_availability_or_holiday.available_from
+			end     = appointment_availability_or_holiday.available_till
+			weekday = appointment_availability_or_holiday.day_number
+			logger.debug('Considering Availability from {} to {} for weekday {}'.format(start, end, weekday))
+			portion = self.availability[self.availability.index.weekday == (weekday-1)].between_time(start,end) #selects the weekdays and then the specific hours
+			set_to  = 1 
+		elif isinstance(appointment_availability_or_holiday, Holiday):
+			start   = appointment_availability_or_holiday.datetime_start
+			end     = appointment_availability_or_holiday.datetime_end
+			logger.debug('Considering {} from {} to {}'.format('Extra Availability' if appointment_availability_or_holiday.kind == AVAILABILITY_EXTRA else 'Holiday', start, end))
+			portion = self.availability[pd.date_range(start=start, end=end, freq=self.minimum_slot)] #select the specific range
+			set_to	= 1 if appointment_availability_or_holiday.kind == AVAILABILITY_EXTRA else 0
+		elif isinstance(appointment_availability_or_holiday, Appointment):
+			start   = appointment_availability_or_holiday.datetime_when
+			end     = start + datetime.timedelta(minutes=appointment_availability_or_holiday.length)
+			logger.debug('Considering General Appointment from {} to {}'.format(start, end))
+			portion = self.availability[pd.date_range(start=start, end=end, freq=self.minimum_slot)] #select the specific range
+			set_to  = 0
+		elif isinstance(appointment_availability_or_holiday, AppointmentTypeLink):
+			start   = appointment_availability_or_holiday.date_when
+			end     = start + datetime.timedelta(minutes=appointment_availability_or_holiday.appointment_type.default_duration)
+			logger.debug('Considering Subject Appointment from {} to {}'.format(start, end))
+			portion = self.availability[pd.date_range(start=start, end=end, freq=self.minimum_slot)] #select the specific range
+			set_to  = 0
+		else:
+			logger.error('Expected Availability, Holiday, Appointment or AppointmentTypeLink objects.')
+			raise TypeError
+
+		if only_working_hours:
+			portion = portion.between_time(self.office_start, self.office_end)
+
+		#limit portion to be changed to the bounds of the object time space (solution 1 of the aforementioned problem)
+		portion = portion[(self.availability.index.min() <= portion.index) & (portion.index <= self.availability.index.max())]
+
+		self.availability[portion.index] = set_to
+
+	def get_availability_percentage(self, only_working_hours=False):
+		'''
+		For multiple values this is the solution: return self.availability.value_counts().div(len(s))[1] * 100 
+		But since it's 0 or 1, this works as well and is faster: return self.availability.mean() * 100
+
+		To test it:
+		import pandas as pd
+		range = pd.date_range(start='2018-10-1', end='2018-10-2 01:00', freq='5T', closed=None)
+		s = pd.Series(index=range, data=0)
+		range2 = pd.date_range(start='2018-10-1 1:00', end='2018-10-1 2:30', freq='5T')
+		s[range2] = 1
+		print(s.value_counts().div(len(s))[1]*100)   # prints 6.312292358803987
+		print(s.mean()*100)							 # prints 6.312292358803987
+		%timeit s.value_counts().div(len(s))[1]*100  # 504 µs ± 19.2 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
+		%timeit s.mean()*100                         # 56.3 µs ± 1.66 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
+		'''
+		if only_working_hours:
+			availability = self.availability.between_time(self.office_start, self.office_end)
+		else:
+			availability = self.availability
+
+		return availability.mean() * 100 #better to isolate the operation in case we change it later
+
+	def is_available(self, only_working_hours=False):
+		'''
+		Returns True if on the selected period is available at least 50% of the time
+		Otherwise returns False
+		'''
+		return self.get_availability_percentage(only_working_hours=only_working_hours) > 50.0
+
+	def plot_availability(self):
+		'''
+		Plot availability chart.
+		'''
+		fig = plt.figure() #create new figure. This should ensure thread safe method
+		ax=fig.gca() #get current axes
+		matplotlib.rcParams['hatch.linewidth'] = 1
+		logger.debug('business_hours: {} {}'.format(self.office_start, self.office_end))
+		business_hours = self.business_hours = pd.Series(index=self.range, data=0)
+		mask = business_hours.between_time(self.office_start, self.office_end).index
+		business_hours[mask] = 1
+		ax = business_hours.plot(kind='area', alpha = 0.33, color='#1190D8', label='Business Hours', legend=True, ax=ax)
+
+		#calculate good xticks
+		hours = self._get_duration().total_seconds()/3600
+		n_ticks = int(hours/24)
+		if n_ticks == 0:
+			minutes = self._get_duration().total_seconds()/60
+			n_ticks = int(minutes/60)
+			if n_ticks == 0:
+				n_ticks = 1
+			xticks=self.availability.asfreq('{}T'.format(n_ticks)).index
+		else:
+			xticks=self.availability.asfreq('{}H'.format(n_ticks)).index
+
+		title = 'Availability for {} from {} to {}'.format(self.name, self.start.strftime('%Y/%m/%d %H:%M'), self.end.strftime('%Y/%m/%d %H:%M'))
+
+		ax = self.availability.plot(figsize=(16, 8), grid = True, 
+			title=title, legend=True, label='Availability', color='#00af52',
+			xticks=xticks, ax=ax, yticks=[0,1])
+		
+		ax.fill_between(self.availability.index, self.availability.tolist(), facecolor="none", hatch='//', edgecolor="#00af52", alpha=1, linewidth=0.5)
+		ax.set_axisbelow(True)
+		ax.yaxis.grid(color='gray', linewidth=0.5, alpha=0)
+		ax.xaxis.grid(color='gray', linewidth=0.5, alpha=1)
+		ax.set_yticklabels(['False', 'True'])
+		ax.set_ylabel('Is Available ?')
+		ax.set_xlabel('Date & Time')
+
+		fig.tight_layout()
+		fig.savefig('{}_{}_{}.pdf'.format(self.name, self.start.strftime('%Y%m%d%H%M'), self.end.strftime('%Y%m%d%H%M')))
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/smash/web/static/js/daily_planning.js b/smash/web/static/js/daily_planning.js
index 0febcc3c23bb664a06691491f767e0ec8c31bf38..9ae40d26537594521ff1412d448d72862255ad31 100644
--- a/smash/web/static/js/daily_planning.js
+++ b/smash/web/static/js/daily_planning.js
@@ -106,7 +106,11 @@ function get_subjects_events(day) {
         });
         var holidays = data.holidays;
         $.each(holidays, function (index, event) {
-            event.backgroundColor = '#FFAAAA !important';
+            if(event.kind == 'H'){
+                event.backgroundColor = '#FFAAAA !important';
+            }else{
+                event.backgroundColor = '#AAFFAA !important';
+            }
             event.start = $.fullCalendar.moment(event.link_when);
             event.end = $.fullCalendar.moment(event.link_end);
             event.rendering = 'background';
@@ -120,8 +124,10 @@ function get_subjects_events(day) {
             var boxSubject = $("<div class='box box-primary'/>").css('border-top-color', subject.color);
             var boxBody = $("<div class='box-body' id='subject_" + subject.id + "'>");
             var boxHeader = $("<div class='box-header with-border'/>");
-            var title_subject = $("<h4>" + subject.name + "( " + subject.start + ") <span style='float:right;padding-right:5px;'>" + subject.location + "</span></h4>");
+
+            var title_subject = $(`<h4>${subject.name} (${subject.start}) <span style='float:right;padding-right:5px;'>${subject.location}</span> <span style='float:left;padding-right:5px;'><a title="Edit appointment" target="_blank" href="/appointments/edit/${subject.appointment_id}"><i class="fa fa-pencil-square"></i></a></span></h4>`);
             boxHeader.append(title_subject);
+            title_subject.find('a[title]').tooltip();
             $.each(subject.events, function (index_event, event) {
                 if (event.link_when) {
                     event.title = event.short_title;
@@ -159,8 +165,9 @@ function get_subjects_events(day) {
             var boxSubject = $("<div class='box box-primary'/>").css('border-top-color', location.color);
             var boxBody = $("<div class='box-body' id='location_" + location.id + "'>");
             var boxHeader = $("<div class='box-header with-border'/>");
-            var title_location = $("<h4>" + location.name + " <span style='float:right;padding-right:5px;'>" + location.location + "</span></h4>");
+            var title_location = $(`<h4>${location.name}<span style='float:right;padding-right:5px;'>${location.location}</span><span style='float:left;padding-right:5px;'><a title="Edit appointment" target="_blank" href="/appointments/edit/${location.id}"><i class="fa fa-pencil-square"></i></a></span></h4>`);
             boxHeader.append(title_location);
+            title_location.find('a[title]').tooltip();
             $.each(location.events, function (index_event, event) {
                 if (event.link_who) {
                     event.title = event.short_title;
@@ -287,7 +294,6 @@ $(document).ready(function () {
                                     appointmentsCleared.splice(index, 1);
                                 }
                             }
-
                         }
                     });
                     $.post({
@@ -363,10 +369,27 @@ $(document).ready(function () {
         droppable: true,
         resourceAreaWidth: '15%',
         resourceLabelText: 'Workers',
-        resources: resources_url,
+        refetchResourcesOnNavigate: true,
+        resourceOrder: '-availability',
+        resources: function(callback){
+                        setTimeout(function(){
+                            var view = $('#calendar').fullCalendar('getView');
+                            $.ajax({
+                                url: resources_url,
+                                type: 'GET',
+                                cache: false,
+                                data: {
+                                    start_date: view.start.format('YYYY-MM-DD'),
+                                    }
+                                }).then(function(resources){
+                                    var checked_roles = $('.role_list_item > input:checked').map( (i,e) => e.value).toArray();
+                                    resources = resources.filter(resource => checked_roles.includes(resource.role));
+                                    callback(resources)
+                                });                  
+                        }, 0);
+        },
         events: [],
         eventRender: function (event, element) {
-
             if (event.rendering !== 'background') {
                 var content =
                     element.popover({
@@ -383,7 +406,6 @@ $(document).ready(function () {
                         html: true
                     });
             } else {
-
             }
         },
         selectAllow: function (selectInfo) {
@@ -403,7 +425,41 @@ $(document).ready(function () {
         selectHelper: true,
         drop: function (date, jsEvent, ui, resourceId) {
             $(this).remove();
+        },
+        eventAfterAllRender: function(view){
+            //RESIZE COLUMNS AND ENABLE HORIZONTAL SCROLL
+            window.onresize = function(event) {
+                resizeCalendarColumns();
+            };
+            
+            //ADD EDIT BUTTONS
+            $('.fc-resource-cell').not('.anchored').each(function(resourceColumn){
+                $(this).addClass('anchored');
+                var worker_id = $(this).data('resource-id');
+                var span = $(`<div style='display:block;'></div>`);
+                var add_extra_availability_link = `<a style="padding-right:5px;" title="Add Extra Availability or Holiday" target="_blank" href="/doctors/${worker_id}/holiday/add"><i class="fa fa-plus-square-o" aria-hidden="true"></i></a>`;
+                var edit_worker_link = `<a style="padding-right:5px;" title="Edit Worker" target="_blank" href="/doctors/edit/${worker_id}"><i class="fa fa-pencil-square" aria-hidden="true"></i></a>`;
+                
+                $(span).append($(add_extra_availability_link));
+                $(span).append($(edit_worker_link));
+                $(this).append(span);
+                //$(this).css('padding-left', span.width());
+                $(this).find('a[title]').tooltip();
+            });
+
         }
     });
 })
-;
\ No newline at end of file
+;
+
+//RESIZE COLUMNS AND ENABLE HORIZONTAL SCROLL
+function resizeCalendarColumns(){
+    if($('.fc-resource-cell').width() <= 150){
+        $('.fc-view-container').width(200*$('.fc-resource-cell').length);
+        $('#calendar').css('overflow-x', 'scroll');
+    }
+    if($('#calendar').width() > 200*$('.fc-resource-cell').length){
+        $('.fc-view-container').width("100%");
+        $('#calendar').css('overflow-x', 'null');
+    }
+}
diff --git a/smash/web/templates/appointments/add.html b/smash/web/templates/appointments/add.html
index b29fc125c36b8e753afa41b7067714f4132f7f2f..bf87695b3f1f00caf74b6db18777f2ec762445be 100644
--- a/smash/web/templates/appointments/add.html
+++ b/smash/web/templates/appointments/add.html
@@ -13,10 +13,22 @@
 
     {% include "includes/datetimepicker.css.html" %}
     <link rel="stylesheet" href="{% static 'css/appointment.css' %}">
+    <style type="text/css">
+        .availability_description {
+            text-align: center !important;
+            margin: 0;
+        }
+    </style>
 {% endblock styles %}
 
 {% block ui_active_tab %}'appointments'{% endblock ui_active_tab %}
-{% block page_header %}New appointment{% endblock page_header %}
+{% block page_header %}
+{% if isGeneral %}
+New general appointment
+{% else %}
+New appointment for visit from {{visit_start}} to {{visit_end}}
+{% endif %}
+{% endblock page_header %}
 {% block page_description %}{% endblock page_description %}
 
 {% block title %}{{ block.super }} - Add new appointment{% endblock %}
@@ -101,8 +113,8 @@
                 "info": true,
                 "autoWidth": false
             });
-
             $('#calendar').fullCalendar({
+                defaultDate: moment('{{visit_start}}'),
                 header: {
                     left: 'prev,next today',
                     center: 'title',
@@ -117,7 +129,7 @@
                         dateString = dateString + " 09:00";
                     }
                     document.getElementById("id_datetime_when").value = dateString;
-
+                    getWorkerAvailability();
                 },
                 eventClick: function (calEvent, jsEvent, view) {
 
@@ -142,6 +154,66 @@
         appointment_type_behaviour($("input[name='appointment_types']"), lengthInput, "{% url 'web.api.appointment_types' %}");
         appointment_flying_team_place_behaviour($("select[name='flying_team']"), $("select[name='location']"));
         appointment_date_change_behaviour($("input[name='datetime_when']"), $("select[name='worker_assigned']"), lengthInput);
+
+        function getWorkerAvailability() {
+            var selected = $('select.search_worker_availability').find(':selected');
+            var worker_id = selected.val();
+            if(worker_id===''){
+                return;
+            }
+
+            var start_date = $('input[name="datetime_when"]').val();
+            start_date = moment(start_date);
+            if(isNaN(start_date)){
+                return;
+            }
+            var ordinalDay = start_date.format('Do');
+            var longStartDate = start_date.format('MMM Do HH:mm');
+
+            $('.availability_description').remove();
+
+            //GET FULL DAY AVAILABILITY
+            $.ajax({
+                data: {
+                    // our hypothetical feed requires UNIX timestamps
+                    start_date: start_date.format('YYYY-MM-DD-HH-mm'),
+                    worker_id: worker_id
+                },
+                url: "{% url 'web.api.get_worker_availability' %}",
+                success: function (doc) {
+                    $('select.search_worker_availability').parent().append(`<p class="availability_description">${ordinalDay} availability: ${doc.availability}%</p>`);
+                }
+            });
+
+            var duration = parseInt($('input[name="length"]').val());
+            if(isNaN(duration)){
+                return;
+            }
+
+            var end_date = start_date.clone().add(duration, 'minutes');
+            var endTime = end_date.format('HH:mm');
+
+            //GET SPECIFIC AVAILABILITY
+            $.ajax({
+                data: {
+                    // our hypothetical feed requires UNIX timestamps
+                    start_date: start_date.format('YYYY-MM-DD-HH-mm'),
+                    end_date: end_date.format('YYYY-MM-DD-HH-mm'),
+                    worker_id: worker_id
+                },
+                url: "{% url 'web.api.get_worker_availability' %}",
+                success: function (doc) {
+                    if(doc.availability<100){
+                        var available = 'No';
+                    }else{
+                        var available = 'Yes';
+                    }
+                    $('select.search_worker_availability').parent().append(`<p class="availability_description">${longStartDate} to ${endTime} availability: ${available} (${doc.availability}%)</p>`);
+                }
+            });
+        }
+
+        $('select.search_worker_availability, input[name="datetime_when"], input[name="length"]').on("change", getWorkerAvailability);
     </script>
 
     {% include "includes/datetimepicker.js.html" %}
diff --git a/smash/web/templates/daily_planning.html b/smash/web/templates/daily_planning.html
index c02b5d7d6e7e9262b53a20f90b1eb9c4d4a261d9..c28fb0192e2eaf4f53d787b3ba30d111ec7b6c8b 100644
--- a/smash/web/templates/daily_planning.html
+++ b/smash/web/templates/daily_planning.html
@@ -13,6 +13,20 @@
     />
     <link rel="stylesheet" href="{% static 'fullcalendar-scheduler/scheduler.min.css' %}">
     <link rel="stylesheet" href="{% static 'css/daily_planning.css' %}">
+    <style type="text/css">
+        .role_label{
+            padding-left: 5px;
+        }
+        #role_list{
+            columns: 3;
+            webkit-columns: 2;
+            -moz-columns: 2;
+        }
+        .role_list_item{
+            list-style: none;
+            list-style-type:none;
+        }
+    </style>
     {% include "includes/datepicker.css.html" %}
 {% endblock styles %}
 
@@ -38,6 +52,13 @@
             </div>
         </div>
     </div>
+    <ul id="role_list">
+     {% for role in worker_study_roles %}
+        <li class="role_list_item">
+            <input type="checkbox" name="{{role.0}}" value="{{role.0}}" id="{{role.0}}" onclick="clicked_role_list_item(this);" checked><label class="role_label" for="{{role.0}}">{{role.1}}</label>
+        </li>
+     {% endfor %}
+    </ul>
 {% endblock maincontent %}
 
 {% block scripts %}
@@ -48,6 +69,11 @@
     <script>
         var resources_url = '{% url 'web.api.workers.daily_planning' %}';
         var events_url = '{% url 'web.api.events_persist' %}';
+        function clicked_role_list_item(item){
+            //var checked = $(item).prop('checked');
+            $('#calendar').fullCalendar('refetchResources');
+        }
+
     </script>
     {% include "includes/datepicker.js.html" %}
     <script src="{% static 'js/daily_planning.js' %}"></script>
diff --git a/smash/web/templates/doctors/add_availability.html b/smash/web/templates/doctors/add_availability.html
index de6dce582dd2ea09ae2faf06b1d29bf4c21d0e03..90c093ca963bb776b32db6201c449dbf7c8b40f1 100644
--- a/smash/web/templates/doctors/add_availability.html
+++ b/smash/web/templates/doctors/add_availability.html
@@ -8,7 +8,7 @@
 {% endblock styles %}
 
 {% block ui_active_tab %}'workers'{% endblock ui_active_tab %}
-{% block page_header %}New worker availability{% endblock page_header %}
+{% block page_header %}Create new availability for <span class="doctor_name">{{ doctor_name }}</span>{% endblock page_header %}
 {% block page_description %}{% endblock page_description %}
 
 {% block title %}{{ block.super }} - Add availability{% endblock %}
diff --git a/smash/web/templates/doctors/add_holiday.html b/smash/web/templates/doctors/add_holiday.html
index 59e2975087f29fa7adf00f386bf03623c09966f5..4a05cfda35db0ed77a11100c16a0946969085948 100644
--- a/smash/web/templates/doctors/add_holiday.html
+++ b/smash/web/templates/doctors/add_holiday.html
@@ -6,10 +6,15 @@
     {{ block.super }}
     {% include "includes/datetimepicker.css.html" %}
     <link rel="stylesheet" href="{% static 'AdminLTE/plugins/awesomplete/awesomplete.css' %}"/>
+    <style type="text/css">
+        .doctor_name {
+            border-bottom: black 1px solid;
+        }
+    </style>
 {% endblock styles %}
 
 {% block ui_active_tab %}'workers'{% endblock ui_active_tab %}
-{% block page_header %}New worker holiday{% endblock page_header %}
+{% block page_header %}Create new holiday or extra availability for <span class="doctor_name">{{ doctor_name }}</span>{% endblock page_header %}
 {% block page_description %}{% endblock page_description %}
 
 {% block title %}{{ block.super }} - Add availability{% endblock %}
@@ -36,8 +41,10 @@
                             <div class="form-group  {% if field.errors %}has-error{% endif %}">
                                 <label for="{# TODO #}" class="col-sm-4 control-label">
                                     {{ field.label }}
+                                    {% if field.help_text %}
+                                        <i class="fa fa-info-circle" aria-hidden="true" data-toggle="tooltip" data-placement="top" title="{{field.help_text}}"></i>
+                                    {% endif %}
                                 </label>
-
                                 <div class="col-sm-8">
                                     {{ field|add_class:'form-control' }}
                                 </div>
diff --git a/smash/web/templates/doctors/breadcrumb.html b/smash/web/templates/doctors/breadcrumb.html
index 549b2357d5ee10f1a13a761f2cd3548d54c8bc29..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.workers' worker_type %}">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 c8435067c97ba02e96a5bec0735a6ed752bbe04b..fb689494e717f705c657633b0dc42508d0968e22 100644
--- a/smash/web/templates/doctors/edit.html
+++ b/smash/web/templates/doctors/edit.html
@@ -117,7 +117,7 @@
             </div>
 
             <div class="box-header with-border">
-                <h3 class="box-title">Holidays</h3>
+                <h3 class="box-title">Holidays and Extra Availabilities</h3>
             </div>
             <div class="box-body">
                 <table id="table" class="table table-bordered table-striped">
@@ -125,6 +125,7 @@
                     <tr>
                         <th>From</th>
                         <th>Until</th>
+                        <th>Kind</th>
                         <th>Info</th>
                         <th>Remove</th>
                     </tr>
@@ -134,6 +135,13 @@
                         <tr>
                             <td>{{ holiday.datetime_start }}</td>
                             <td>{{ holiday.datetime_end }}</td>
+                            <td>
+                                {% for kind in availability_choices %}
+                                    {% if holiday.kind == kind.0 %}
+                                        {{ kind.1 }}
+                                    {% endif %}
+                                {% endfor %}
+                            </td>
                             <td>{{ holiday.info }}</td>
                             <td>
                                 <a href="{% url 'web.views.worker_holiday_delete' holiday.id %}" type="button"
@@ -148,7 +156,7 @@
                 <div class="box-footer">
                     <div class="col-sm-6">
                         <a href="{% url 'web.views.worker_holiday_add' doctor_id %}" type="button"
-                           class="btn btn-block btn-success">Add holiday</a>
+                           class="btn btn-block btn-success">Add Holiday or Extra Availability</a>
                     </div>
                 </div><!-- /.box-footer -->
 
diff --git a/smash/web/templates/doctors/index.html b/smash/web/templates/doctors/index.html
index 93d2bf58d6a0e86f891afa629cab2fadd74b8459..1accfd94d238279684ff6d4fe11d6085b05976b8 100644
--- a/smash/web/templates/doctors/index.html
+++ b/smash/web/templates/doctors/index.html
@@ -8,7 +8,15 @@
 {% endblock styles %}
 
 {% block ui_active_tab %}'workers'{% endblock ui_active_tab %}
-
+{% block page_header %}
+{% if worker_type == 'STAFF' %}
+    Workers
+{% elif worker_type == 'HEALTH_PARTNER' %}
+    Health Partners
+{% elif worker_type == 'VOUCHER_PARTNER' %}
+    Voucher Partners
+{% endif %}
+{% endblock page_header %}
 {% block breadcrumb %}
     {% include "doctors/breadcrumb.html" %}
 {% endblock breadcrumb %}
diff --git a/smash/web/templates/visits/details.html b/smash/web/templates/visits/details.html
index ed73408d2e1030b164c7a6e38be41df5b83c9fb8..62069efad065578c2615da6a13a554e261b11629 100644
--- a/smash/web/templates/visits/details.html
+++ b/smash/web/templates/visits/details.html
@@ -126,7 +126,7 @@
                             <td>{{ app.datetime_when | time:"H:i" }}</td>
                             <td>{{ app.length }}</td>
                             <td>
-                                {% if app.flying_team %}{{ app.worker_assigned.first_name }}
+                                {% if app.flying_team is None %}{{ app.worker_assigned.first_name }}
                                     {{ app.worker_assigned.last_name }}
                                 {% else %} {{ app.flying_team }}
                                 {% endif %}
diff --git a/smash/web/tests/api_views/test_worker.py b/smash/web/tests/api_views/test_worker.py
index c146d560acf741436cef1ba93667a994940d8fdb..9b759f0cfcee629968a1dc2732ffe34406a20d11 100644
--- a/smash/web/tests/api_views/test_worker.py
+++ b/smash/web/tests/api_views/test_worker.py
@@ -1,6 +1,6 @@
 # coding=utf-8
 import json
-
+import datetime
 from django.test import RequestFactory
 from django.urls import reverse
 
@@ -54,6 +54,13 @@ class TestWorkerApi(LoggedInWithWorkerTestCase):
         self.assertEqual(response.status_code, 200)
         self.assertTrue(self.worker.first_name in response.content)
 
+    def test_workers_for_daily_planning_with_start_date(self):
+        today = datetime.datetime.today()
+        start_date = today.strftime("%Y-%m-%d")
+        params = {'start_date': start_date}
+        response = self.client.get(reverse('web.api.workers.daily_planning'), data=params)
+        self.assertEqual(response.status_code, 200)
+
     def test_voucher_partners(self):
         voucher_partner = create_voucher_partner()
         response = self.client.get(reverse('web.api.workers', kwargs={'worker_role': WORKER_STAFF}))
@@ -85,3 +92,32 @@ class TestWorkerApi(LoggedInWithWorkerTestCase):
         for entry in entries:
             count += len(entry["workers"])
         self.assertTrue(count > 0)
+    def test_get_worker_availability(self):
+        today = datetime.datetime.today().replace(hour=8, minute=00, second=0, microsecond=0)
+        availability = Availability.objects.create(person=self.worker, day_number=today.isoweekday(),
+                                                   available_from="8:00", available_till="16:00")
+        availability.save()
+        params={}
+        params['start_date'] = today.strftime("%Y-%m-%d-%H-%M")
+        params['end_date']   = (today+datetime.timedelta(hours=4)).strftime("%Y-%m-%d-%H-%M")
+        params['worker_id']  = self.worker.id
+        response = self.client.get(reverse('web.api.get_worker_availability'), data=params)
+        availability = json.loads(response.content)['availability']
+        self.assertEqual(availability, 100.0)
+        today = today.replace(hour=16, minute=1)
+        params={}
+        params['start_date'] = today.strftime("%Y-%m-%d-%H-%M")
+        params['end_date']   = (today+datetime.timedelta(hours=4)).strftime("%Y-%m-%d-%H-%M")
+        params['worker_id']  = self.worker.id
+        response = self.client.get(reverse('web.api.get_worker_availability'), data=params)
+        availability = json.loads(response.content)['availability']
+        self.assertEqual(availability, 0.0)
+        today = today.replace(hour=14, minute=0)
+        params={}
+        params['start_date'] = today.strftime("%Y-%m-%d-%H-%M")
+        params['end_date']   = (today+datetime.timedelta(hours=4)).strftime("%Y-%m-%d-%H-%M")
+        params['worker_id']  = self.worker.id
+        response = self.client.get(reverse('web.api.get_worker_availability'), data=params)
+        availability = json.loads(response.content)['availability']
+        self.assertEqual(availability, 50.0)
+        
\ No newline at end of file
diff --git a/smash/web/tests/functions.py b/smash/web/tests/functions.py
index 3af08171a7a08d4b512468666240737fd8fd0ef2..ed17deb7e769ffdb6125cb317302840c934b29e6 100644
--- a/smash/web/tests/functions.py
+++ b/smash/web/tests/functions.py
@@ -154,13 +154,13 @@ def get_test_study():
         return create_study("test-study")
 
 
-def create_appointment_type():
+def create_appointment_type(code='C', default_duration=10, description='test'):
     return AppointmentType.objects.create(
-        code="C",
-        default_duration="10",
-        description="test",
+        code=code,
+        default_duration=default_duration,
+        description=description,
     )
-
+    
 
 def create_contact_attempt(subject=None, worker=None):
     if subject is None:
@@ -259,34 +259,43 @@ def create_voucher_partner():
     return worker
 
 
-def create_availability(worker=None):
+def create_availability(worker=None, available_from=None, available_till=None, day_number=MONDAY_AS_DAY_OF_WEEK):
+    if available_from is None:
+        available_from = '8:00'
+    if available_till is None:
+        available_till = '18:00'
+
     if worker is None:
         worker = create_worker()
     availability = Availability.objects.create(person=worker,
-                                               day_number=MONDAY_AS_DAY_OF_WEEK,
-                                               available_from=get_today_midnight_date(),
-                                               available_till=get_today_midnight_date(),
+                                               day_number=day_number,
+                                               available_from=available_from,
+                                               available_till=available_till,
                                                )
     return availability
 
 
-def create_visit(subject=None):
+def create_visit(subject=None, datetime_begin=None, datetime_end=None):
     if subject is None:
         subject = create_study_subject()
-    return Visit.objects.create(datetime_begin=get_today_midnight_date() + datetime.timedelta(days=-31),
-                                datetime_end=get_today_midnight_date() + datetime.timedelta(days=31),
+    if datetime_begin is None:
+        datetime_begin = get_today_midnight_date() + datetime.timedelta(days=-31)
+    if datetime_end is None:
+        datetime_end = get_today_midnight_date() + datetime.timedelta(days=31)
+    return Visit.objects.create(datetime_begin=datetime_begin,
+                                datetime_end=datetime_end,
                                 subject=subject,
                                 is_finished=False)
 
 
-def create_appointment(visit=None, when=None):
+def create_appointment(visit=None, when=None, length=30):
     if visit is None:
         visit = create_visit()
     # if when is None:
     #     when = get_today_midnight_date()
     return Appointment.objects.create(
         visit=visit,
-        length=30,
+        length=length,
         location=get_test_location(),
         status=Appointment.APPOINTMENT_STATUS_SCHEDULED,
         datetime_when=when)
diff --git a/smash/web/tests/test_office_availability.py b/smash/web/tests/test_office_availability.py
new file mode 100644
index 0000000000000000000000000000000000000000..b1184285f2c0c768d27ce8874f3cf776f474f9d0
--- /dev/null
+++ b/smash/web/tests/test_office_availability.py
@@ -0,0 +1,113 @@
+import logging
+
+from django.test import TestCase
+from django.utils import timezone
+import datetime
+import pandas as pd
+from datetime import timedelta
+from functions import create_availability, create_visit, create_appointment, create_appointment_type
+from web.utils import get_weekdays_in_period
+from web.officeAvailability import OfficeAvailability
+from web.models.holiday import Holiday
+from web.models.availability import Availability
+from web.models.appointment import Appointment
+from web.models.appointment_type_link import AppointmentTypeLink
+from web.models.constants import AVAILABILITY_HOLIDAY, AVAILABILITY_EXTRA
+from web.tests.functions import create_worker
+
+logger = logging.getLogger(__name__)
+
+class OfficeAvailabilityTest(TestCase):
+	def test_availability_cases(self):
+		#
+		today = timezone.now()
+		start_date = datetime.datetime(today.year, today.month, today.day, tzinfo=today.tzinfo) #today midnight
+		end_date = start_date + datetime.timedelta(days=1)
+
+		office_availability = OfficeAvailability('FirstName LastName', 
+			start=start_date, end=end_date, office_start='8:00', office_end='18:00')
+		
+		#no availabilties added yet
+		self.assertEqual(office_availability.is_available(), False)
+		self.assertEqual(office_availability.is_available(only_working_hours=True), False)
+		self.assertEqual(office_availability.get_availability_percentage(only_working_hours=True), 0.0)
+		self.assertEqual(office_availability.get_availability_percentage(only_working_hours=False), 0.0)
+
+		#add availabilty from 8:00 to 18:00
+		weekday = list(get_weekdays_in_period(start_date, end_date))[0]
+		availability = create_availability(available_from='8:00', available_till='18:00', day_number=weekday)
+		office_availability.consider_this(availability)
+		self.assertEqual(office_availability.is_available(only_working_hours=True), True)
+		self.assertEqual(office_availability.is_available(), False) #less than 50%
+		self.assertEqual(office_availability.get_availability_percentage(only_working_hours=True), 100.0)
+		self.assertEqual(office_availability.get_availability_percentage(only_working_hours=False), 41.70714781401804) # ((10*(60)+1)/(24*60.0+1))*100 That +1 is the zero minute
+
+		#add holiday from 16:00 to 18:00 # 2 hours less availability
+		start_date = datetime.datetime(today.year, today.month, today.day, 16, 00, tzinfo=today.tzinfo)
+		end_date = start_date + datetime.timedelta(hours=2)
+		holiday = Holiday(person=create_worker(), datetime_start=start_date, datetime_end=end_date, kind=AVAILABILITY_HOLIDAY)
+		office_availability.consider_this(holiday)
+		self.assertEqual(office_availability.is_available(only_working_hours=True), True)
+		self.assertEqual(office_availability.is_available(), False)  #less than 50%
+		self.assertEqual(office_availability.get_availability_percentage(only_working_hours=True), 79.86688851913478) # ((8*60)/(10*60.0+1))*100  # the bordwer minute is 0, then no +1
+		self.assertEqual(office_availability.get_availability_percentage(only_working_hours=False), 33.31020124913255) # ((8*60)/(24*60.0+1))*100
+		
+		#add extra availability from 17:00 to 18:00 # 1 hour more availability 
+		start_date = datetime.datetime(today.year, today.month, today.day, 17, 00, tzinfo=today.tzinfo)
+		end_date = start_date + datetime.timedelta(hours=1)
+		extra_availability = Holiday(person=create_worker(), datetime_start=start_date, datetime_end=end_date, kind=AVAILABILITY_EXTRA)
+		office_availability.consider_this(extra_availability)
+		self.assertEqual(office_availability.is_available(only_working_hours=True), True)
+		self.assertEqual(office_availability.is_available(), False)  #less than 50%
+		self.assertEqual(office_availability.get_availability_percentage(only_working_hours=True), 90.01663893510815) # ((9*60+1)/(10*60.0+1))*100 # the border minute is now 1 then +1
+		self.assertEqual(office_availability.get_availability_percentage(only_working_hours=False), 37.543372657876475)
+		
+		#add appointment from 9:00 to 10:00 # 1 hour less availability
+			#create visit
+		visit_start_date = start_date - datetime.timedelta(days=31)
+		visit_end_date   = end_date + datetime.timedelta(days=31)
+		visit = create_visit(subject=None, datetime_begin=visit_start_date, datetime_end=visit_end_date)
+			#create appointment
+		appointment_typeA = create_appointment_type(code='A', default_duration=40, description='test1')
+		appointment_typeB = create_appointment_type(code='B', default_duration=20, description='test2')
+		appointment_when = datetime.datetime(today.year, today.month, today.day, 9, 00, tzinfo=today.tzinfo)
+		appointment = create_appointment(visit=visit, when=appointment_when, length=60)
+		worker = create_worker()
+		app_type_linkA = AppointmentTypeLink(appointment=appointment, date_when=appointment_when, appointment_type=appointment_typeA, worker=worker)
+		app_type_linkB = AppointmentTypeLink(appointment=appointment, date_when=appointment_when+datetime.timedelta(minutes=20), appointment_type=appointment_typeB, worker=worker)
+		appointment.save()
+		#the availability percentage should be the same as before adding the extra availability
+		office_availability.consider_this(appointment)
+		self.assertEqual(office_availability.is_available(only_working_hours=True), True)
+		self.assertEqual(office_availability.is_available(), False)  #less than 50%
+		self.assertEqual(office_availability.get_availability_percentage(only_working_hours=True), 79.86688851913478) # ((8*60)/(10*60.0+1))*100  # the bordwer minute is 0, then no +1
+		self.assertEqual(office_availability.get_availability_percentage(only_working_hours=False), 33.31020124913255) # ((8*60)/(24*60.0+1))*100
+		#consider the 2 AppointmentTypeLinks. The availability percentage shouldn't change
+		office_availability.consider_this(app_type_linkA)
+		office_availability.consider_this(app_type_linkB)
+		self.assertEqual(office_availability.is_available(only_working_hours=True), True)
+		self.assertEqual(office_availability.is_available(), False)  #less than 50%
+		self.assertEqual(office_availability.get_availability_percentage(only_working_hours=True), 79.86688851913478) # ((8*60)/(10*60.0+1))*100  # the bordwer minute is 0, then no +1
+		self.assertEqual(office_availability.get_availability_percentage(only_working_hours=False), 33.31020124913255) # ((8*60)/(24*60.0+1))*100
+
+		#force add availability from 9:00 to 10:00 # 1 hour more availability
+		start_date = datetime.datetime(today.year, today.month, today.day, 9, 00, tzinfo=today.tzinfo).replace(second=0, microsecond=0)
+		end_date = start_date + datetime.timedelta(hours=1)
+		office_availability.add_availability(pd.date_range(start=start_date, end=end_date, freq='1T'), only_working_hours=False)
+		self.assertEqual(office_availability.is_available(only_working_hours=True), True)
+		self.assertEqual(office_availability.is_available(), False)  #less than 50%
+		self.assertEqual(office_availability.get_availability_percentage(only_working_hours=True), 90.01663893510815) # ((9*60+1)/(10*60.0+1))*100 # the border minute is now 1 then +1
+		self.assertEqual(office_availability.get_availability_percentage(only_working_hours=False), 37.543372657876475)
+
+		#force remove availability from 9:00 to 12:00 # 3 hour less availability
+		start_date = datetime.datetime(today.year, today.month, today.day, 9, 00, tzinfo=today.tzinfo).replace(second=0, microsecond=0)
+		end_date = start_date + datetime.timedelta(hours=3)
+		office_availability.remove_availability(pd.date_range(start=start_date, end=end_date, freq='1T'), only_working_hours=True)
+		self.assertEqual(office_availability.is_available(only_working_hours=True), True)
+		self.assertEqual(office_availability.is_available(), False)  #less than 50%
+		self.assertEqual(office_availability.get_availability_percentage(only_working_hours=True), 59.900166389351085) # ((6*60)/(10*60.0+1))*100 # the border minute is 0 then no +1
+		self.assertEqual(office_availability.get_availability_percentage(only_working_hours=False), 24.98265093684941)
+
+
+
+
diff --git a/smash/web/tests/view/test_appointments.py b/smash/web/tests/view/test_appointments.py
index a1544f213bdcfcb70a699f4b9299c61faa5b069d..e17bb743efcab2bf5f7b467e2786592f7ed1c566 100644
--- a/smash/web/tests/view/test_appointments.py
+++ b/smash/web/tests/view/test_appointments.py
@@ -4,11 +4,11 @@ import logging
 from django.core.files.uploadedfile import SimpleUploadedFile
 from django.urls import reverse
 
-from web.forms import SubjectEditForm, StudySubjectEditForm, AppointmentEditForm
+from web.forms import SubjectEditForm, StudySubjectEditForm, AppointmentEditForm, AppointmentAddForm
 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, \
-    create_flying_team, format_form_field
+    create_flying_team, format_form_field, get_test_location
 from web.views.notifications import get_today_midnight_date
 
 logger = logging.getLogger(__name__)
@@ -19,6 +19,41 @@ class AppointmentsViewTests(LoggedInTestCase):
         super(AppointmentsViewTests, self).setUp()
         create_worker(self.user, True)
 
+    def test_get_add_general_appointment(self):
+        #test get without visit_id
+        response = self.client.get(reverse('web.views.appointment_add_general'))
+        self.assertEqual(response.status_code, 200)
+    def test_get_add_appointment(self):
+        #test get with visit_id
+        subject = create_study_subject()
+        visit = create_visit(subject)
+        response = self.client.get(reverse('web.views.appointment_add', 
+            kwargs={'visit_id': visit.id}))
+        self.assertEqual(response.status_code, 200)
+
+    def test_post_add_general_appointment(self):
+        location = get_test_location()
+        form_appointment = AppointmentAddForm(user=self.user)
+        form_data = {}
+        form_data['datetime_when'] = datetime.datetime.today()
+        form_data['location'] = location.id
+        form_data['length'] = 10
+        response = self.client.post(reverse('web.views.appointment_add_general'), data=form_data)
+        self.assertEqual(response.status_code, 302)
+
+    def test_add_appointment(self):
+        subject = create_study_subject()
+        visit = create_visit(subject)
+        location = get_test_location()
+        form_data = {}
+        form_appointment = AppointmentAddForm(user=self.user)
+        form_data['datetime_when'] = datetime.datetime.today()
+        form_data['location'] = location.id
+        form_data['length'] = 10
+        response = self.client.post(reverse('web.views.appointment_add', 
+            kwargs={'visit_id': visit.id}), data=form_data)
+        self.assertEqual(response.status_code, 302)
+    
     def test_appointments_list_request(self):
         response = self.client.get(reverse('web.views.appointments'))
         self.assertEqual(response.status_code, 200)
diff --git a/smash/web/tests/view/test_utils.py b/smash/web/tests/view/test_utils.py
new file mode 100644
index 0000000000000000000000000000000000000000..ba1df2735e2b85d48cc3884560800401b9f07ccf
--- /dev/null
+++ b/smash/web/tests/view/test_utils.py
@@ -0,0 +1,22 @@
+import logging
+
+from django.test import TestCase
+
+from web.utils import get_weekdays_in_period
+
+from datetime import date
+import datetime
+
+logger = logging.getLogger(__name__)
+
+class Utils(TestCase):
+    def test_get_weekdays_in_period(self):
+        fromdate = date(2018,10,9)
+        todate = date(2018,10,12)
+        weekdays = get_weekdays_in_period(fromdate, todate)
+        self.assertEqual(weekdays, {2, 3, 4})
+
+        todate  = datetime.datetime(2018, 10, 12, 00, 00, 00)
+        fromdate = datetime.datetime(2018, 10, 9, 00, 00, 00)
+        weekdays = get_weekdays_in_period(fromdate, todate)
+        self.assertEqual(weekdays, {2, 3, 4})
\ No newline at end of file
diff --git a/smash/web/utils.py b/smash/web/utils.py
new file mode 100644
index 0000000000000000000000000000000000000000..1bbb74ecc18c444298e49ba893ed84ea865e128d
--- /dev/null
+++ b/smash/web/utils.py
@@ -0,0 +1,31 @@
+# coding=utf-8
+from django.utils import timezone
+import datetime
+from datetime import timedelta
+
+def get_today_midnight_date():
+	today = timezone.now()
+	today_midnight = datetime.datetime(today.year, today.month, today.day, tzinfo=today.tzinfo)
+	return today_midnight
+
+def get_weekdays_in_period(fromdate, todate):
+    '''
+    fromdate and todate must be generated using datetime.date or datetime.datetime like:
+    
+    from datetime import date
+    fromdate = date(2010,1,1)
+    todate = date(2010,3,31)
+
+    fromdate = datetime.datetime(2018, 10, 3, 15, 00, 00)
+    todate = datetime.datetime.today()
+
+    but both dates must have the same format ! 
+    todate is not included in the range
+    
+    Weekdays are returned as isoweekdays like the form described in week_choices from constants.py (starting at 1)
+    '''
+    if todate < fromdate:
+        return set([])
+    day_generator = (fromdate + timedelta(day) for day in xrange((todate - fromdate).days))
+    weekdays = set([date.isoweekday() for date in day_generator])
+    return weekdays
\ No newline at end of file
diff --git a/smash/web/views/appointment.py b/smash/web/views/appointment.py
index c4a9ddf1f5a37259e369de156f44b5ea6031d564..bc782e45a686222e32dab5465f3cbff5f158cd2b 100644
--- a/smash/web/views/appointment.py
+++ b/smash/web/views/appointment.py
@@ -1,7 +1,7 @@
 # coding=utf-8
 import logging
 import re
-
+import datetime
 from django.contrib import messages
 from django.core.exceptions import ValidationError
 from django.shortcuts import get_object_or_404, redirect
@@ -11,7 +11,7 @@ from web.models.appointment_list import APPOINTMENT_LIST_APPROACHING, APPOINTMEN
 from . import wrap_response
 from web.forms import AppointmentDetailForm, AppointmentEditForm, AppointmentAddForm, SubjectEditForm, \
     StudySubjectEditForm
-from ..models import Appointment, StudySubject, MailTemplate
+from ..models import Appointment, StudySubject, MailTemplate, Visit
 
 logger = logging.getLogger(__name__)
 
@@ -40,6 +40,13 @@ def appointment_details(request, id):
 
 
 def appointment_add(request, visit_id=None):
+    if visit_id is not None:
+        visit  = get_object_or_404(Visit, id=visit_id)
+        visit_start = visit.datetime_begin.strftime("%Y-%m-%d")
+        visit_end   = visit.datetime_end.strftime("%Y-%m-%d")
+    else:
+        visit_start = datetime.datetime.today().strftime("%Y-%m-%d")
+        visit_end   = datetime.datetime.today().strftime("%Y-%m-%d")
     if request.method == 'POST':
         form = AppointmentAddForm(request.POST, request.FILES, user=request.user)
         if form.is_valid():
@@ -49,11 +56,16 @@ def appointment_add(request, visit_id=None):
                 return redirect('web.views.appointments')
             else:
                 return redirect('web.views.visit_details', id=visit_id)
+        else:
+            raise ValidationError("Invalid request: Errors: {}. Non field errors: {}".format(form.errors, form.non_field_errors()))
+
     else:
         form = AppointmentAddForm(user=request.user)
 
     return wrap_response(request, 'appointments/add.html',
-                         {'form': form, 'visitID': visit_id, 'full_list': APPOINTMENT_LIST_GENERIC})
+                         {'form': form, 'visitID': visit_id, 'isGeneral': visit_id is None, 
+                         'visit_start': visit_start, 'visit_end': visit_end, 
+                         'full_list': APPOINTMENT_LIST_GENERIC})
 
 
 def appointment_edit(request, id):
diff --git a/smash/web/views/daily_planning.py b/smash/web/views/daily_planning.py
index 3988cc23ed7125c0415a36c730e2ed4c1d45c7aa..40ab776c754d5bc3c8b89e8d9e1ec70701669f53 100644
--- a/smash/web/views/daily_planning.py
+++ b/smash/web/views/daily_planning.py
@@ -3,7 +3,10 @@ import logging
 
 from django.views.generic import TemplateView
 from . import wrap_response
+from web.models.worker_study_role import STUDY_ROLE_CHOICES
+
 class TemplateDailyPlannerView(TemplateView):
     def get(self, request, *args, **kwargs):
-        context = self.get_context_data(**kwargs)        
+        context = self.get_context_data(**kwargs)
+        context['worker_study_roles'] = STUDY_ROLE_CHOICES
         return wrap_response(request, 'daily_planning.html', context)
\ No newline at end of file
diff --git a/smash/web/views/notifications.py b/smash/web/views/notifications.py
index edee35b6d89590df8eb4fc67d16d236946c42f6a..20246b9ecd1b4a674e7cf42437c0b63588b2bbb9 100644
--- a/smash/web/views/notifications.py
+++ b/smash/web/views/notifications.py
@@ -4,8 +4,8 @@ import logging
 
 from django.contrib.auth.models import User, AnonymousUser
 from django.db.models import Count, Case, When, Q, F, Max
-from django.utils import timezone
 
+from web.utils import get_today_midnight_date
 from web.models import Study, Worker, StudySubject, Visit, Appointment, Location, MissingSubject, InconsistentSubject
 from web.models.constants import GLOBAL_STUDY_ID, VOUCHER_STATUS_NEW
 
@@ -327,7 +327,3 @@ def get_filter_locations(user):
         return worker.locations.all()
 
 
-def get_today_midnight_date():
-    today = timezone.now()
-    today_midnight = datetime.datetime(today.year, today.month, today.day, tzinfo=today.tzinfo)
-    return today_midnight
diff --git a/smash/web/views/worker.py b/smash/web/views/worker.py
index f3b135734d8325c450e626997898ab440caad0f8..c2ca3cba16c1cfe96f53e26a1e3d22549bd42524 100644
--- a/smash/web/views/worker.py
+++ b/smash/web/views/worker.py
@@ -6,7 +6,7 @@ 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.constants import WEEKDAY_CHOICES, GLOBAL_STUDY_ID, AVAILABILITY_CHOICES
 from web.models.worker import worker_type_by_worker
 from web.models.worker_study_role import WORKER_STAFF
 from . import wrap_response
@@ -55,6 +55,7 @@ def worker_edit(request, worker_id):
                              'holidays': holidays,
                              'doctor_id': worker_id,
                              'weekdays': WEEKDAY_CHOICES,
+                             'availability_choices': AVAILABILITY_CHOICES,
                              "worker_type": worker_type
                          })
 
@@ -69,7 +70,7 @@ def worker_availability_delete(request, availability_id):
     availability = Availability.objects.filter(id=availability_id)
     doctor_id = availability[0].person.id
     availability.delete()
-    return redirect(worker_edit, doctor_id=doctor_id)
+    return redirect(worker_edit, worker_id=doctor_id)
 
 
 def worker_availability_add(request, doctor_id):
@@ -78,13 +79,14 @@ def worker_availability_add(request, doctor_id):
         form = AvailabilityAddForm(request.POST, request.FILES)
         if form.is_valid():
             form.save()
-            return redirect(worker_edit, doctor_id=doctor_id)
+            return redirect(worker_edit, worker_id=doctor_id)
     else:
         form = AvailabilityAddForm(initial={'person': worker})
     return wrap_response(request, 'doctors/add_availability.html',
                          {
                              'form': form,
-                             'doctor_id': doctor_id
+                             'doctor_id': doctor_id,
+                             'doctor_name': unicode(worker)
                          })
 
 
@@ -94,7 +96,7 @@ def worker_availability_edit(request, availability_id):
         form = AvailabilityEditForm(request.POST, request.FILES, instance=availability)
         if form.is_valid():
             form.save()
-            return redirect(worker_edit, doctor_id=availability.person_id)
+            return redirect(worker_edit, worker_id=availability.person_id)
     else:
         form = AvailabilityEditForm(instance=availability)
     return wrap_response(request, 'doctors/edit_availability.html',
@@ -109,7 +111,7 @@ def worker_holiday_delete(request, holiday_id):
     holiday = Holiday.objects.filter(id=holiday_id)
     doctor_id = holiday[0].person.id
     holiday.delete()
-    return redirect(worker_edit, doctor_id=doctor_id)
+    return redirect(worker_edit, worker_id=doctor_id)
 
 
 def worker_holiday_add(request, doctor_id):
@@ -119,13 +121,15 @@ def worker_holiday_add(request, doctor_id):
         doctor = doctors[0]
     if request.method == 'POST':
         form = HolidayAddForm(request.POST, request.FILES)
+
         if form.is_valid():
             form.save()
-            return redirect(worker_edit, doctor_id=doctor_id)
+            return redirect(worker_edit, worker_id=doctor_id)
     else:
         form = HolidayAddForm(initial={'person': doctor})
         return wrap_response(request, 'doctors/add_holiday.html',
                              {
                                  'form': form,
-                                 'doctor_id': doctor_id
+                                 'doctor_id': doctor_id,
+                                 'doctor_name': unicode(doctor)
                              })