From 753a55c04d9c84b776f3a14c007da00c8d48ec04 Mon Sep 17 00:00:00 2001 From: Adan Perez Rodriguez Date: Mon, 30 Mar 2026 20:47:26 +0100 Subject: [PATCH 1/4] Task-2 feat: Add occupancy percentage calculation to dashboard view --- pms/views.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/pms/views.py b/pms/views.py index f38563933..eaa074bd7 100644 --- a/pms/views.py +++ b/pms/views.py @@ -209,13 +209,20 @@ def get(self, request): .aggregate(Sum('total')) ) + # get occupancy percentage + total_rooms = Room.objects.count() + total_confirmed_bookings = Booking.objects.filter(state="NEW").count() + occupancy_percentage = 0 + if total_rooms > 0: + occupancy_percentage = (total_confirmed_bookings / total_rooms) * 100 # use formula to calculate occupancy percentage (Cantidad total de reservas en estado confirmada / número de habitaciones existentes.) + # preparing context data dashboard = { 'new_bookings': new_bookings, 'incoming_guests': incoming, 'outcoming_guests': outcoming, - 'invoiced': invoiced - + 'invoiced': invoiced, + 'occupancy_percentage': round(occupancy_percentage, 2) } context = { From db4cc3a751cbdaa3d777c3fff66ba4b30d835d98 Mon Sep 17 00:00:00 2001 From: Adan Perez Rodriguez Date: Mon, 30 Mar 2026 20:51:00 +0100 Subject: [PATCH 2/4] Task-2 feat: Add occupancy percentage display to dashboard --- pms/templates/dashboard.html | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pms/templates/dashboard.html b/pms/templates/dashboard.html index 10f0285cc..03f48fa7c 100644 --- a/pms/templates/dashboard.html +++ b/pms/templates/dashboard.html @@ -22,6 +22,10 @@

{{dashboard.outcoming_guests}}

Total facturado

€ {% if dashboard.invoiced.total__sum == None %}0.00{% endif %} {{dashboard.invoiced.total__sum|floatformat:2}}

+
+
% Ocupación
+

{{dashboard.occupancy_percentage}} %

+
{% endblock content%} \ No newline at end of file From 258ce32b89deda9ca64b0a55c41fe610d96780c0 Mon Sep 17 00:00:00 2001 From: Adan Perez Rodriguez Date: Mon, 30 Mar 2026 20:51:27 +0100 Subject: [PATCH 3/4] Task-2 style: Improve layout of dashboard cards for better responsiveness --- pms/templates/dashboard.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pms/templates/dashboard.html b/pms/templates/dashboard.html index 03f48fa7c..a95cb4383 100644 --- a/pms/templates/dashboard.html +++ b/pms/templates/dashboard.html @@ -4,7 +4,7 @@

Dashboard

Hoy
-
+
Reservas hechas

{{dashboard.new_bookings}}

From 0fb708cde9bf274104e1dc0fb8a7731d7ccad1dd Mon Sep 17 00:00:00 2001 From: Adan Perez Rodriguez Date: Mon, 30 Mar 2026 21:04:50 +0100 Subject: [PATCH 4/4] Task-2 test: Created unit tests in DashboardViewTestCase handling normal, empty and zero-division cases --- pms/tests.py | 46 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/pms/tests.py b/pms/tests.py index 7ce503c2d..442153eab 100644 --- a/pms/tests.py +++ b/pms/tests.py @@ -1,3 +1,47 @@ from django.test import TestCase +from django.urls import reverse +from datetime import date +from .models import Room, Room_type, Booking, Customer -# Create your tests here. +class DashboardViewTestCase(TestCase): + def setUp(self): + # Create Room Types + self.single_type = Room_type.objects.create(name="Individual", price=20, max_guests=1) + + # Create Rooms + self.room1 = Room.objects.create(name="101", room_type=self.single_type, description="Room 101") + self.room2 = Room.objects.create(name="102", room_type=self.single_type, description="Room 102") + self.room3 = Room.objects.create(name="103", room_type=self.single_type, description="Room 103") + self.room4 = Room.objects.create(name="104", room_type=self.single_type, description="Room 104") + + # Create Customer + self.customer = Customer.objects.create(name="Adan Perez", email="adan@perez.com", phone="123009988") + + def test_occupancy_percentage_with_no_bookings(self): + # 0 bookings, 4 rooms === occupancy should be 0.0 + response = self.client.get('/dashboard/') + self.assertEqual(response.status_code, 200) + self.assertEqual(response.context['dashboard']['occupancy_percentage'], 0.0) + + def test_occupancy_percentage_with_bookings(self): + # Create *1 NEW* booking and *1 DEL* booking + Booking.objects.create( + state="NEW", checkin=date(2026, 4, 1), checkout=date(2026, 4, 5), + room=self.room1, guests=1, customer=self.customer, total=80, code="B001" + ) + Booking.objects.create( + state="DEL", checkin=date(2026, 4, 1), checkout=date(2026, 4, 5), + room=self.room2, guests=1, customer=self.customer, total=80, code="B002" + ) + + # *1 confirmed* booking out of 4 rooms = 25.0% + response = self.client.get('/dashboard/') + self.assertEqual(response.status_code, 200) + self.assertEqual(response.context['dashboard']['occupancy_percentage'], 25.0) + + def test_occupancy_percentage_zero_rooms(self): + Room.objects.all().delete() + # *0 confirmed* booking out of 0 rooms = 0.0% (to avoid divide by zero) + response = self.client.get('/dashboard/') + self.assertEqual(response.status_code, 200) + self.assertEqual(response.context['dashboard']['occupancy_percentage'], 0.0)