From 99a5539e8fcb01bafcb536a9b4a1ff6a5c0f0f5f Mon Sep 17 00:00:00 2001
From: Piotr Gawron <piotr.gawron@uni.lu>
Date: Tue, 31 Oct 2017 16:07:32 +0100
Subject: [PATCH] list of appointments contains information about
 availabilities

---
 smash/web/api_urls.py                       |  1 +
 smash/web/api_views/worker.py               | 33 ++++++++++++++++++++-
 smash/web/models/worker.py                  |  8 +++++
 smash/web/static/js/appointment.js          | 28 +++++++++++++++--
 smash/web/templates/appointments/index.html | 12 +++++++-
 smash/web/tests/api_views/test_redcap.py    |  1 -
 smash/web/tests/api_views/test_worker.py    | 30 +++++++++++++++++++
 7 files changed, 108 insertions(+), 5 deletions(-)

diff --git a/smash/web/api_urls.py b/smash/web/api_urls.py
index 4db32fe7..93f32c28 100644
--- a/smash/web/api_urls.py
+++ b/smash/web/api_urls.py
@@ -43,6 +43,7 @@ urlpatterns = [
     url(r'^specializations$', worker.specializations, name='web.api.specializations'),
     url(r'^units$', worker.units, name='web.api.units'),
     url(r'^workers$', worker.workers_for_daily_planning, name='web.api.workers'),
+    url(r'^workers/availabilities$', worker.availabilities, name='web.api.workers.availabilities$'),
 
     # daily planning events
     url(r'^events/(?P<date>\d{4}-\d{2}-\d{2})/$', daily_planning.events, name='web.api.events'),
diff --git a/smash/web/api_views/worker.py b/smash/web/api_views/worker.py
index 5183e3cd..d9edbcc1 100644
--- a/smash/web/api_views/worker.py
+++ b/smash/web/api_views/worker.py
@@ -1,7 +1,10 @@
+import datetime
+
 from django.contrib.auth.decorators import login_required
 from django.http import JsonResponse
+from django.utils import timezone
 
-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_availabilities
 from ..models import Worker
 
 
@@ -33,3 +36,31 @@ def workers_for_daily_planning(request):
         }
         workers_list_for_json.append(worker_dict_for_json)
     return JsonResponse(workers_list_for_json, safe=False)
+
+
+@login_required
+def availabilities(request):
+    result = []
+    min_date = request.GET.get("start_date")
+    max_date = request.GET.get("end_date")
+
+    workers = get_workers_for_daily_planning(request)
+
+    min_date = datetime.datetime.strptime(min_date, "%Y-%m-%d").replace(tzinfo=timezone.now().tzinfo)
+    max_date = datetime.datetime.strptime(max_date, "%Y-%m-%d").replace(tzinfo=timezone.now().tzinfo)
+
+    while min_date <= max_date:
+        str_date = min_date.strftime('%Y-%m-%d')
+        date_result = {"date": str_date, "workers": []}
+        for worker in workers:
+            if len(get_availabilities(worker, str_date)) > 0:
+                date_result["workers"].append({
+                    "worker_id": worker.id,
+                    "initials": worker.initials(),
+                })
+        result.append(date_result)
+        min_date += datetime.timedelta(days=1)
+
+    return JsonResponse({
+        "availabilities": result,
+    })
diff --git a/smash/web/models/worker.py b/smash/web/models/worker.py
index dd9a2205..8923532e 100644
--- a/smash/web/models/worker.py
+++ b/smash/web/models/worker.py
@@ -111,3 +111,11 @@ class Worker(models.Model):
 
     def __unicode__(self):
         return "%s %s" % (self.first_name, self.last_name)
+
+    def initials(self):
+        result = ""
+        if len(self.first_name) > 0:
+            result += self.first_name[0]
+        if len(self.last_name) > 0:
+            result += self.last_name[0]
+        return result
diff --git a/smash/web/static/js/appointment.js b/smash/web/static/js/appointment.js
index a2e1b222..a4d594ba 100644
--- a/smash/web/static/js/appointment.js
+++ b/smash/web/static/js/appointment.js
@@ -202,11 +202,35 @@ function appointment_date_change_behaviour(datetime_picker, worker_select, minut
 
 }
 
-function get_calendar_events_function(source, allow_url_redirection) {
+function get_calendar_events_function(source, allow_url_redirection, day_headers, workerAvailabilitiesUrl) {
     if (allow_url_redirection === undefined) {
         allow_url_redirection = false;
     }
     return function (start, end, timezone, callback) {
+        if (day_headers !== undefined) {
+            console.log("XXXX");
+            $.ajax({
+                data: {
+                    start_date: start.format(),
+                    end_date: end.format()
+                },
+                url: workerAvailabilitiesUrl,
+                success: function (doc) {
+                    for (var i = 0; i < doc.availabilities.length; i++) {
+                        const entry = doc.availabilities[i];
+                        var initials = '';
+                        for (var j = 0; j < entry.workers.length; j++) {
+                            initials += entry.workers[j].initials + ", ";
+                        }
+                        var element = day_headers[entry.date];
+                        if (element !== undefined) {
+                            element.innerHTML = initials;
+                        }
+                    }
+                }
+            });
+
+        }
         $.ajax({
             data: {
                 // our hypothetical feed requires UNIX timestamps
@@ -220,7 +244,7 @@ function get_calendar_events_function(source, allow_url_redirection) {
 
                     const entry = doc.data[i];
                     var title = entry.subject;
-                    if (title != "") {
+                    if (title !== "") {
                         title += " (" + entry.nd_number + "); type: " + entry.type;
                     } else {
                         title = entry.title
diff --git a/smash/web/templates/appointments/index.html b/smash/web/templates/appointments/index.html
index ef999fa5..81a642dc 100644
--- a/smash/web/templates/appointments/index.html
+++ b/smash/web/templates/appointments/index.html
@@ -75,6 +75,7 @@
 
     <script>
         $(function () {
+            var dayHeaders = {};
             var approachingTable = $('#approaching_table');
             var table = approachingTable.DataTable({
                 serverSide: true,
@@ -115,6 +116,12 @@
                 weekNumbers: true,
                 startParam: "start_date",
                 endParam: "end_date",
+                dayRender: function (date, cell) {
+                    var element = document.createElement("div");
+                    cell[0].appendChild(element);
+                    dayHeaders[$(cell[0]).attr("data-date")] = element;
+                },
+
                 eventRender: function (event, element) {
                     var content = "<ul>";
                     if (event.phone_number) {
@@ -143,7 +150,10 @@
                     });
                     console.log(event);
                 },
-                events: get_calendar_events_function("{% url 'web.api.appointments' full_list %}", true),
+                events: get_calendar_events_function(
+                    "{% url 'web.api.appointments' full_list %}",
+                    true, dayHeaders,
+                    "{% url 'web.api.workers.availabilities$' %}")
             });
         });
     </script>
diff --git a/smash/web/tests/api_views/test_redcap.py b/smash/web/tests/api_views/test_redcap.py
index 5c1c774b..276c09f2 100644
--- a/smash/web/tests/api_views/test_redcap.py
+++ b/smash/web/tests/api_views/test_redcap.py
@@ -1,5 +1,4 @@
 # coding=utf-8
-import json
 
 from django.contrib.auth.models import User
 from django.test import Client
diff --git a/smash/web/tests/api_views/test_worker.py b/smash/web/tests/api_views/test_worker.py
index 061f4ca8..33e4b71d 100644
--- a/smash/web/tests/api_views/test_worker.py
+++ b/smash/web/tests/api_views/test_worker.py
@@ -1,8 +1,12 @@
 # coding=utf-8
 import json
 
+from django.test import RequestFactory
 from django.urls import reverse
 
+from web.models import Availability
+from web.models.constants import TUESDAY_AS_DAY_OF_WEEK
+from web.api_views.worker import availabilities
 from web.tests import LoggedInWithWorkerTestCase
 
 
@@ -47,3 +51,29 @@ class TestApi(LoggedInWithWorkerTestCase):
         response = self.client.get(reverse('web.api.workers'))
         self.assertEqual(response.status_code, 200)
         self.assertTrue(self.worker.first_name in response.content)
+
+    def test_empty_availabilities(self):
+        factory = RequestFactory()
+        request = factory.get('/api/workers?start_date=2017-10-20&end_date=2017-11-20')
+        request.user = self.user
+
+        result = availabilities(request)
+        entries = json.loads(result.content)['availabilities']
+        for entry in entries:
+            self.assertEqual(0, len(entry["workers"]))
+
+    def test_non_empty_availabilities(self):
+        factory = RequestFactory()
+        request = factory.get('/api/workers?start_date=2017-10-20&end_date=2017-11-20')
+        request.user = self.user
+
+        availability = Availability.objects.create(person=self.worker, day_number=TUESDAY_AS_DAY_OF_WEEK,
+                                                   available_from="8:00", available_till="16:00")
+        availability.save()
+
+        result = availabilities(request)
+        entries = json.loads(result.content)['availabilities']
+        count = 0;
+        for entry in entries:
+            count += len(entry["workers"])
+        self.assertTrue(count > 0)
-- 
GitLab