diff --git a/smash/web/api_views/daily_planning.py b/smash/web/api_views/daily_planning.py
index a72f05e973e8b7d8c505b3cf2cbfc2e809d8bbe0..116b021e4fae2189287eaa7964b34d289dbdac7e 100644
--- a/smash/web/api_views/daily_planning.py
+++ b/smash/web/api_views/daily_planning.py
@@ -1,13 +1,17 @@
 import datetime
 import json
+import logging
 from operator import itemgetter
 
 from django.contrib.auth.decorators import login_required
 from django.http import JsonResponse
 from django.shortcuts import get_object_or_404
 
-from ..models import Appointment, AppointmentTypeLink, Worker, Availability, Holiday
-from ..views.notifications import get_filter_locations
+from web.views import e500_error
+from web.models import Appointment, AppointmentTypeLink, Worker, Availability, Holiday
+from web.views.notifications import get_filter_locations
+
+logger = logging.getLogger(__name__)
 
 RANDOM_COLORS = [
     '#%02X%02X%02X' % (8, 218, 217),
@@ -184,6 +188,52 @@ def get_conflicts(worker, date):
     return result
 
 
+def get_generic_appointment_events(request, date):
+    result = {}
+
+    appointments = Appointment.objects.filter(
+        datetime_when__date=date,
+        location__in=get_filter_locations(request.user),
+        status=Appointment.APPOINTMENT_STATUS_SCHEDULED,
+        visit__isnull=True).all()
+
+    for appointment in appointments:
+        if appointment.location_id not in result:
+            appointment_data = {
+                'name': "GENERAL",
+                'id': appointment.id,
+                'color': RANDOM_COLORS[len(RANDOM_COLORS)-1],
+                'start': "",
+                'location': str(appointment.location),
+                'events': []
+            }
+            result[appointment.location_id] = appointment_data
+
+        link_when = appointment.datetime_when
+        link_end = None
+        if link_when is not None:
+            link_when = link_when.replace(tzinfo=None)
+            link_end = link_when + datetime.timedelta(minutes=appointment.length)
+        event = {
+            'title': appointment.title(),
+            'short_title': appointment.title(),
+            'duration': build_duration(appointment.length),
+            'id': 'app-{}'.format(appointment.id),
+            'appointment_id': appointment.id,
+            'link_when': link_when,
+            'link_who': appointment.worker_assigned_id,
+            'link_end': link_end,
+            'location': str(appointment.location),
+            'flying_team_location': unicode(appointment.flying_team),
+            'appointment_start': appointment.datetime_when.replace(tzinfo=None, hour=7, minute=0),
+            'appointment_end': appointment.datetime_when.replace(tzinfo=None, hour=19, minute=0),
+        }
+        appointment_events = result[appointment.location_id]['events']
+        appointment_events.append(event)
+
+    return result.values()
+
+
 @login_required
 def events(request, date):
     appointments = Appointment.objects.filter(
@@ -233,6 +283,8 @@ def events(request, date):
             subject_events = subjects[appointment_subject.id]['events']
             subject_events.append(event)
 
+    generic_appointment_events = get_generic_appointment_events(request, date)
+
     availabilities = []
     holidays = []
     workers = get_workers_for_daily_planning(request)
@@ -243,6 +295,7 @@ def events(request, date):
 
     return JsonResponse({
         "data": subjects.values(),
+        "generic": generic_appointment_events,
         'availabilities': availabilities,
         'holidays': holidays
     })
@@ -275,22 +328,39 @@ def availabilities(request, date):
 
 @login_required
 def events_persist(request):
-    event_links = json.loads(request.POST.get('events_to_persist'))
-    for event_link in event_links:
-        try:
-            when = datetime.datetime.strptime(event_link['start'], '%Y-%m-%dT%H:%M:00')
-        except ValueError:
-            when = datetime.datetime.strptime(event_link['start'][0:-6], '%Y-%m-%dT%H:%M:00')
-        worker_id = event_link['link_who']
-        link_id = event_link['link_id']
-        appointment_type_link = get_object_or_404(AppointmentTypeLink, pk=link_id)
-        appointment_type_link.worker_id = worker_id
-        appointment_type_link.date_when = when
-        appointment_type_link.save()
-    events_to_clear = json.loads(request.POST.get('events_to_clear'))
-    for link_id in events_to_clear:
-        appointment_type_link = get_object_or_404(AppointmentTypeLink, pk=link_id)
-        appointment_type_link.worker_id = None
-        appointment_type_link.date_when = None
-        appointment_type_link.save()
-    return JsonResponse({}, status=201)
+    try:
+        event_links = json.loads(request.POST.get('events_to_persist'))
+        for event_link in event_links:
+            try:
+                when = datetime.datetime.strptime(event_link['start'], '%Y-%m-%dT%H:%M:00')
+            except ValueError:
+                when = datetime.datetime.strptime(event_link['start'][0:-6], '%Y-%m-%dT%H:%M:00')
+            worker_id = event_link['link_who']
+            if 'link_id' in event_link:
+                link_id = event_link['link_id']
+                appointment_type_link = get_object_or_404(AppointmentTypeLink, pk=link_id)
+                appointment_type_link.worker_id = worker_id
+                appointment_type_link.date_when = when
+                appointment_type_link.save()
+            else:
+                logger.info(event_link)
+                appointment_id = event_link['appointment_id']
+                appointment = get_object_or_404(Appointment, pk=appointment_id)
+                appointment.worker_assigned_id = worker_id
+                appointment.datetime_when = when
+                appointment.save()
+        events_to_clear = json.loads(request.POST.get('events_to_clear'))
+        for link_id in events_to_clear:
+            appointment_type_link = get_object_or_404(AppointmentTypeLink, pk=link_id)
+            appointment_type_link.worker_id = None
+            appointment_type_link.date_when = None
+            appointment_type_link.save()
+        appointments_to_clear = json.loads(request.POST.get('appointments_to_clear'))
+        for appointment_id in appointments_to_clear:
+            appointment = get_object_or_404(Appointment, pk=appointment_id)
+            appointment.worker_assigned_id = None
+            appointment.save()
+        return JsonResponse({}, status=201)
+    except Exception as e:
+        logger.error(e, exc_info=True)
+        return e500_error(request)
diff --git a/smash/web/models/appointment.py b/smash/web/models/appointment.py
index 9db12586d0d83c0f61f9eba87d55260192eb5c8a..f4a6c043a3dc13da9bed30f999ae19cc42fa6caa 100644
--- a/smash/web/models/appointment.py
+++ b/smash/web/models/appointment.py
@@ -118,7 +118,12 @@ class Appointment(models.Model):
 
     def title(self):
         if self.visit is None:
-            return self.comment.replace("\n", ";").replace("\r", ";")
+            title = "N/A"
+            if self.comment is not None:
+                title = self.comment.replace("\n", ";").replace("\r", ";")
+            if title == "":
+                title = "N/A"
+            return title
         else:
             title = self.visit.subject.first_name + " " + self.visit.subject.last_name + " type: "
             for appointment_type in self.appointment_types.all():
diff --git a/smash/web/static/js/daily_planning.js b/smash/web/static/js/daily_planning.js
index ec43541e6f3b96c601c2a5a48487afdc28e1d50f..55e0d1b34ffd017fbaff6eb0ac23018abb7eb9ce 100644
--- a/smash/web/static/js/daily_planning.js
+++ b/smash/web/static/js/daily_planning.js
@@ -27,8 +27,9 @@ var overlaps = (function () {
 })();
 
 var eventsCleared = [];
+var appointmentsCleared = [];
 
-function add_event(event, color, subjectId, boxBody) {
+function add_event(event, color, subjectId, locationId, boxBody) {
     var eventElement = $('<div class="fc-event ui-draggable ui-draggable-handle hidden-print">' + event.title +
         '<span style="float:right;padding-right:5px;">' + event.duration + '</span></div>'
         )
@@ -56,7 +57,9 @@ function add_event(event, color, subjectId, boxBody) {
         original_duration: event.duration,
         subject: event.subject,
         subject_id: subjectId,
+        location_id: locationId,
         id: event.id,
+        appointment_id: event.appointment_id,
         link_id: event.link_id,
         link_who: event.link_who,
         link_when: event.link_when,
@@ -134,7 +137,7 @@ function get_subjects_events(day) {
                     };
                     $('#calendar').fullCalendar('renderEvent', event, true);
                 } else {
-                    add_event(event, subject.color, subject.id, boxBody);
+                    add_event(event, subject.color, subject.id, undefined, boxBody);
                 }
             });
             boxSubject.append(boxHeader);
@@ -146,19 +149,65 @@ function get_subjects_events(day) {
                 }
             });
         });
+        var location_based_general_appointments = data.generic;
+        $.each(location_based_general_appointments, function (index, location) {
+            var divSubject = $("<div class='col-md-4 col-lg-3 col-sm-12 subjects-events'/>");
+            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>");
+            boxHeader.append(title_location);
+            $.each(location.events, function (index_event, event) {
+                if (event.link_who) {
+                    event.title = event.short_title;
+                    event.color = location.color + ' !important';
+                    event.start = $.fullCalendar.moment(event.link_when);
+                    event.end = $.fullCalendar.moment(event.link_end);
+                    event.resourceId = event.link_who.toString();
+                    event.location_id = location.id;
+                    event.original_duration = event.duration;
+                    event.constraint = {
+                        start: $.fullCalendar.moment(event.appointment_start),
+                        end: $.fullCalendar.moment(event.appointment_end)
+                    };
+                    $('#calendar').fullCalendar('renderEvent', event, true);
+                } else {
+                    add_event(event, location.color, undefined, location.id, boxBody);
+                }
+            });
+            boxSubject.append(boxHeader);
+            boxSubject.append(boxBody);
+            divSubject.append(boxSubject);
+            $("#subjects").append(divSubject);
+            divSubject.droppable({
+                drop: function (event, ui) {
+                }
+            });
+        });
+
     });
 }
 
 function remove_event(event) {
     $('#calendar').fullCalendar('removeEvents', event.id);
-    var selector = '#subject_' + event.subject_id;
+    var selector;
+    if (event.subject_id !== undefined) {
+        selector = '#subject_' + event.subject_id;
+    } else {
+        selector = '#location_' + event.location_id;
+    }
+
     var boxBody = $(selector);
     event.duration = event.original_duration;
     event.removed = true;
     //remove !important
     event.color = event.color.substring(0, 7);
-    eventsCleared.push(event.link_id);
-    add_event(event, event.color, event.subject_id, boxBody);
+    if (event.link_id !== undefined) {
+        eventsCleared.push(event.link_id);
+    } else {
+        appointmentsCleared.push(event.appointment_id);
+    }
+    add_event(event, event.color, event.subject_id, event.location_id, boxBody);
 }
 
 $(document).ready(function () {
@@ -199,20 +248,30 @@ $(document).ready(function () {
                         if (calendar_event.rendering !== "background") {
                             eventsToPersist.push({
                                 'link_id': calendar_event.link_id,
+                                'appointment_id': calendar_event.appointment_id,
                                 'link_who': parseInt(calendar_event.resourceId),
                                 'start': calendar_event.start.format()
                             });
-                            var index = eventsCleared.indexOf(calendar_event.link_id);
-                            if (index > -1) {
-                                eventsCleared.splice(index, 1);
+                            if (calendar_event.link_id !== undefined) {
+                                var index = eventsCleared.indexOf(calendar_event.link_id);
+                                if (index > -1) {
+                                    eventsCleared.splice(index, 1);
+                                }
+                            } else {
+                                var index = appointmentsCleared.indexOf(calendar_event.appointment_id);
+                                if (index > -1) {
+                                    appointmentsCleared.splice(index, 1);
+                                }
                             }
+
                         }
                     });
                     $.post({
                         url: events_url,
                         data: {
                             events_to_persist: JSON.stringify(eventsToPersist),
-                            events_to_clear: JSON.stringify(eventsCleared)
+                            events_to_clear: JSON.stringify(eventsCleared),
+                            appointments_to_clear: JSON.stringify(appointmentsCleared)
                         },
                         dataType: "json"
                     }).done(function (data) {
@@ -281,19 +340,20 @@ $(document).ready(function () {
         events: [],
         eventRender: function (event, element) {
             if (event.rendering !== 'background') {
-                element.popover({
-                    title: event.short_title,
-                    container: 'body',
-                    placement: 'bottom',
-                    trigger: 'click',
-                    content: '<ul>' +
-                    '<li>' + event.subject + '</li>' +
-                    '<li>' + event.start.format(TIME_FORMAT) + ' - ' + event.end.format(TIME_FORMAT) + '</li>' +
-                    '<li>Appointment starts: ' + event.constraint.start.format(TIME_FORMAT) + '</li>' +
-                    '<li>Location: ' + (event.location !== FLYING_TEAM_LABEL ? event.location : event.flying_team_location + ' (FT)') + '</li>' +
-                    '</ul>',
-                    html: true
-                });
+                var content =
+                    element.popover({
+                        title: event.short_title,
+                        container: 'body',
+                        placement: 'bottom',
+                        trigger: 'click',
+                        content: '<ul>' +
+                        '<li>' + (event.subject !== undefined ? event.subject : 'NO SUBJECT') + '</li>' +
+                        '<li>' + event.start.format(TIME_FORMAT) + ' - ' + event.end.format(TIME_FORMAT) + '</li>' +
+                        (event.subject !== undefined ? '<li>Appointment starts: ' + event.constraint.start.format(TIME_FORMAT) + '</li>' : '') +
+                        '<li>Location: ' + (event.location !== FLYING_TEAM_LABEL ? event.location : event.flying_team_location + ' (FT)') + '</li>' +
+                        '</ul>',
+                        html: true
+                    });
             } else {
 
             }
diff --git a/smash/web/tests/api_views/test_daily_planning.py b/smash/web/tests/api_views/test_daily_planning.py
index d8c96868f541b4abcf09e40a45ea38d676b0cf96..257e4d7abdd681e9a03c028189879b05160b4622 100644
--- a/smash/web/tests/api_views/test_daily_planning.py
+++ b/smash/web/tests/api_views/test_daily_planning.py
@@ -7,7 +7,7 @@ from django.test import Client, RequestFactory
 from django.test import TestCase
 from django.urls import reverse
 
-from web.api_views.daily_planning import get_workers_for_daily_planning
+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.constants import TUESDAY_AS_DAY_OF_WEEK
 from web.tests.functions import create_worker, create_subject, create_appointment, create_flying_team, create_visit, \
@@ -195,3 +195,19 @@ class TestApi(TestCase):
 
         workers = get_workers_for_daily_planning(request)
         self.assertFalse(invalid_worker in workers)
+
+    def test_get_generic_appointment_events(self):
+        factory = RequestFactory()
+        request = factory.get('/api/workers')
+        request.user = self.user
+
+        appointment = create_appointment()
+        appointment.datetime_when = datetime.datetime.now().replace(year=2017, month=9, day=5,
+                                                                    hour=12)
+        appointment.length = 30
+        appointment.location = self.worker.locations.all()[0]
+        appointment.visit = None
+        appointment.save()
+
+        events = get_generic_appointment_events(request, "2017-09-05")
+        self.assertEqual(1, len(events))