From 90aa2cc960533c1784c7e2e48bf6cb2e04bc8abe Mon Sep 17 00:00:00 2001
From: Carlos Vega <carlos.vega@uni.lu>
Date: Thu, 18 Oct 2018 16:31:19 +0200
Subject: [PATCH] added little text below "Worker conducting the assessment"
 with the availability percentage

---
 smash/web/api_urls.py                     |  3 +
 smash/web/api_views/worker.py             | 28 ++++++++++
 smash/web/forms/appointment_form.py       |  4 ++
 smash/web/templates/appointments/add.html | 68 ++++++++++++++++++++++-
 4 files changed, 102 insertions(+), 1 deletion(-)

diff --git a/smash/web/api_urls.py b/smash/web/api_urls.py
index 372aa370..61777145 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/worker.py b/smash/web/api_views/worker.py
index 0a06231d..836fa83d 100644
--- a/smash/web/api_views/worker.py
+++ b/smash/web/api_views/worker.py
@@ -93,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/forms/appointment_form.py b/smash/web/forms/appointment_form.py
index 83b40597..a832eb19 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/templates/appointments/add.html b/smash/web/templates/appointments/add.html
index a931b3a5..bf87695b 100644
--- a/smash/web/templates/appointments/add.html
+++ b/smash/web/templates/appointments/add.html
@@ -13,6 +13,12 @@
 
     {% 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 %}
@@ -123,7 +129,7 @@ New appointment for visit from {{visit_start}} to {{visit_end}}
                         dateString = dateString + " 09:00";
                     }
                     document.getElementById("id_datetime_when").value = dateString;
-
+                    getWorkerAvailability();
                 },
                 eventClick: function (calEvent, jsEvent, view) {
 
@@ -148,6 +154,66 @@ New appointment for visit from {{visit_start}} to {{visit_end}}
         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" %}
-- 
GitLab