diff --git a/smash/web/models.py b/smash/web/models.py index 170690befbed6227eebfec5f2b8a61208187b113..3567021a5adba3c071f3361dc9c76aa3da27c4aa 100644 --- a/smash/web/models.py +++ b/smash/web/models.py @@ -214,6 +214,12 @@ class Item (models.Model): default=False, verbose_name='Is the item fixed?' ) + + disposable = models.BooleanField( + default=False, + verbose_name='Disposable set' + ) + name = models.CharField(max_length=255, verbose_name='Name' ) diff --git a/smash/web/templates/equipment_and_rooms/index.html b/smash/web/templates/equipment_and_rooms/index.html index 6c7a5f4fb99b8217171a0f4d0739cd09df2405e6..95d68215f8a6193d98efb7ef6bf61095c662c7fb 100644 --- a/smash/web/templates/equipment_and_rooms/index.html +++ b/smash/web/templates/equipment_and_rooms/index.html @@ -10,6 +10,7 @@ {% endblock breadcrumb %} {% block maincontent %} +{% comment %} <div class="box box-danger box-solid"> <div class="box-header with-border"> <h3 class="box-title">Not yet implemented</h3> @@ -27,8 +28,12 @@ <!-- /.box-body --> </div> +{% endcomment %} + <div class="row"> + {% comment %} <div class="col-md-3"> + <div class="bg-red-active small-box"> <div class="inner"> <h4>Types of equipment</h4> @@ -71,22 +76,24 @@ </a> </div> </div> + {% endcomment %} <div class="col-md-3"> <div class="bg-yellow-active small-box"> <div class="inner"> - <h4>Equipment requests</h4> + <h4>Kit requests</h4> <p> </p> </div> <div class="icon"> <i class="ion ion-compose"></i> </div> - <a href="#" class="small-box-footer"> - Edit <i class="fa fa-arrow-circle-right"></i> + <a href="{% url 'web.views.kit_requests' %}" class="small-box-footer"> + See <i class="fa fa-arrow-circle-right"></i> </a> </div> + {% comment %} <div class="bg-yellow small-box"> <div class="inner"> <h4>Equipment in rooms</h4> @@ -100,8 +107,10 @@ Edit <i class="fa fa-arrow-circle-right"></i> </a> </div> + {% endcomment %} </div> + {% comment %} <div class="col-md-3"> <div class="bg-green-active small-box"> <div class="inner"> @@ -145,5 +154,7 @@ </a> </div> </div> + {% endcomment %} + </div> {% endblock maincontent %} diff --git a/smash/web/templates/equipment_and_rooms/kit_requests.html b/smash/web/templates/equipment_and_rooms/kit_requests.html new file mode 100644 index 0000000000000000000000000000000000000000..6f5154b8aed715cbc0d5e27d200cd85ac8814898 --- /dev/null +++ b/smash/web/templates/equipment_and_rooms/kit_requests.html @@ -0,0 +1,48 @@ +{% extends "_base.html" %} + +{% block ui_active_tab %}'equipment_and_rooms'{% endblock ui_active_tab %} +{% block page_header %} + Kits required between {{ start_date | date:"Y-m-d" }} and {% ifequal end_date '' %} end of time {% else %} {{ end_date | date:"Y-m-d" }} {% endifequal %} +{% endblock page_header %} +{% block page_description %} +{% endblock page_description %} + +{% block breadcrumb %} +{% include "equipment_and_rooms/breadcrumb.html" %} +{% endblock breadcrumb %} + +{% block maincontent %} + +<div class="row"> + + + <div class="col-md-12"> + <table id="visit_table" class="table table-bordered table-striped"> + <thead> + <tr> + <th>Date</th> + <th>Kits</th> + </tr> + </thead> + <tbody> + {% for appointment in appointments %} + <tr> + <td>{{ appointment.datetime_when | date:"Y-m-d H:i"}} </td> + <td> + {% for type in appointment.appointment_types.all %} + {% for item in type.required_equipment.all %} + {% if item.disposable %} + {{ item.name }}, + {% endif %} + {% endfor %} + {% endfor %} + </td> + </tr> + {% endfor %} + </tbody> + </table> + </div> + + +</div> +{% endblock maincontent %} diff --git a/smash/web/tests/functions.py b/smash/web/tests/functions.py index c8c748908ff4ba8ee947fa06dfcc513efdf5457e..520601b637e923bc3825a17787eccd68caf1a6c7 100644 --- a/smash/web/tests/functions.py +++ b/smash/web/tests/functions.py @@ -40,13 +40,17 @@ def create_worker(): email='jacob@bla', ) -def create_visit(subject): +def create_visit(subject = None): + if subject == None: + subject= create_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), subject =subject, is_finished = False) -def create_appointment(visit): +def create_appointment(visit= None): + if visit == None: + visit = create_visit() return Appointment.objects.create( visit = visit, length = 30, diff --git a/smash/web/tests/test_view_kit_request.py b/smash/web/tests/test_view_kit_request.py new file mode 100644 index 0000000000000000000000000000000000000000..6b32ea7e142954bb750a77cf80c40af4fcc39042 --- /dev/null +++ b/smash/web/tests/test_view_kit_request.py @@ -0,0 +1,76 @@ +from django.test import TestCase, RequestFactory +from django.urls import reverse + +from web.views import * + +from web.tests.functions import * + +class ViewFunctionsTests(TestCase): + def setUp(self): + self.factory = RequestFactory() + self.user = create_user() + + def test_kit_requests(self): + request = self.factory.get(reverse('web.views.kit_requests')); + request.user = self.user + response = kit_requests(request); + self.assertEqual(response.status_code, 200) + + def test_kit_requests_2(self): + item_name = "Test item to be ordered" + item = Item.objects.create(disposable=True, name=item_name) + appointment_type = create_appointment_type() + appointment_type.required_equipment.add(item) + appointment_type.save() + + appointment = create_appointment() + appointment.datetime_when = get_today_midnight_date() + datetime.timedelta(days=2) + appointment.appointment_types.add(appointment_type) + appointment.save() + + request = self.factory.get(reverse('web.views.kit_requests')); + request.user = self.user + response = kit_requests(request); + self.assertEqual(response.status_code, 200) + + self.assertTrue(item_name in response.content) + + def test_kit_requests_4(self): + item_name = "Test item to be ordered" + item = Item.objects.create(disposable=True, name=item_name) + appointment_type = create_appointment_type() + appointment_type.required_equipment.add(item) + appointment_type.save() + + appointment = create_appointment() + appointment.datetime_when = get_today_midnight_date() + datetime.timedelta(days=2) + appointment.appointment_types.add(appointment_type) + appointment.status = Appointment.APPOINTMENT_STATUS_CANCELLED + appointment.save() + + request = self.factory.get(reverse('web.views.kit_requests')); + request.user = self.user + response = kit_requests(request); + self.assertEqual(response.status_code, 200) + + self.assertFalse(item_name in response.content) + + def test_kit_requests_3(self): + item_name = "Test item to be ordered" + item = Item.objects.create(disposable=True, name=item_name) + appointment_type = create_appointment_type() + appointment_type.required_equipment.add(item) + appointment_type.save() + + appointment = create_appointment() + appointment.datetime_when = get_today_midnight_date() + datetime.timedelta(days=2) + appointment.appointment_types.add(appointment_type) + appointment.location = create_location("other_loc") + appointment.save() + + request = self.factory.get(reverse('web.views.kit_requests')); + request.user = self.user + response = kit_requests(request); + self.assertEqual(response.status_code, 200) + + self.assertFalse(not item_name in response.content) diff --git a/smash/web/urls.py b/smash/web/urls.py index 2129f7b67af2873d70618d465c2a5329f09902e8..e2dadb712d672e226dad1a5c978287a28e2aa345 100644 --- a/smash/web/urls.py +++ b/smash/web/urls.py @@ -56,6 +56,9 @@ urlpatterns = [ url(r'^equipment_and_rooms$', views.equipment_and_rooms, name='web.views.equipment_and_rooms'), url(r'^equipment_and_rooms/eqdef$', views.equipment_def, name='web.views.equipment_def'), + url(r'^equipment_and_rooms/kit_requests$', views.kit_requests, name='web.views.kit_requests'), + url(r'^equipment_and_rooms/kit_requests/(?P<start_date>\w+)/(?P<end_date>\w+)/$', views.kit_requests, name='web.views.kit_requests'), + url(r'^mail_templates$', views.mail_templates, name='web.views.mail_templates'), diff --git a/smash/web/views.py b/smash/web/views.py index 0466b85a2d91d14c6653619c31a6280eca8a4197..fe3d78c268b7d988cf8db26efef5091c2dce7469 100644 --- a/smash/web/views.py +++ b/smash/web/views.py @@ -15,6 +15,7 @@ import datetime from django.db.models import Count from django.db.models import Case from django.db.models import When +from django.utils.dateparse import parse_datetime import csv @@ -76,12 +77,15 @@ class NotificationCount(object): def get_filter_locations(user): worker = None + if isinstance(user, User): workers = Worker.objects.filter(user=user) if len(workers)>0: worker = workers[0] - else: + elif isinstance(user, Worker): worker = user + elif user!=None: + raise TypeError("Unknown class type: "+user.__class__.__name__) if worker==None or worker.locations.count() == 0: return Location.objects.all() @@ -699,3 +703,34 @@ def write_appointments_to_csv(writer): def export(request): return wrap_response(request, 'export/index.html',{}) + +def get_kit_requests(user, start_date = '', end_date = ''): + if start_date =='': + start_date = get_today_midnight_date() + datetime.timedelta(days=1) + end_date = start_date + datetime.timedelta(days=7) + else : + start_date = parse_datetime(start_date) + if end_date != '': + end_date = parse_datetime(end_date) + + appointment_types = AppointmentType.objects.filter(required_equipment__disposable=True) + + appointments = Appointment.objects.filter( + appointment_types__in = appointment_types, + datetime_when__gt = start_date, + location__in = get_filter_locations(user), + status = Appointment.APPOINTMENT_STATUS_SCHEDULED, + ) + if end_date!='': + appointments = appointments.filter(datetime_when__lt = end_date) + + result = { + 'start_date' : start_date, + 'end_date' : end_date, + 'appointments' : appointments, + } + return result + +def kit_requests(request,start_date = '', end_date = ''): + + return wrap_response(request, 'equipment_and_rooms/kit_requests.html', get_kit_requests(request.user, start_date, end_date))