From 58260796f50f8c911556c86155dd747fb3023fe8 Mon Sep 17 00:00:00 2001 From: juansheba10 Date: Sun, 29 Mar 2026 23:32:00 +0100 Subject: [PATCH] Add occupancy percentage widget to dashboard --- pms/templates/dashboard.html | 4 +++ pms/tests.py | 59 ++++++++++++++++++++++++++++++++++-- pms/views.py | 11 +++++-- 3 files changed, 69 insertions(+), 5 deletions(-) diff --git a/pms/templates/dashboard.html b/pms/templates/dashboard.html index 10f0285cc..67a2ef136 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}}%

+
{% endblock content%} \ No newline at end of file diff --git a/pms/tests.py b/pms/tests.py index 7ce503c2d..b814fd9ef 100644 --- a/pms/tests.py +++ b/pms/tests.py @@ -1,3 +1,58 @@ -from django.test import TestCase +from datetime import date -# Create your tests here. +from django.test import TestCase, Client +from django.urls import reverse + +from .models import Room, Room_type, Booking, Customer + + +class DashboardOccupancyTest(TestCase): + def setUp(self): + self.client = Client() + self.room_type = Room_type.objects.create(name="Individual", price=20, max_guests=1) + self.room1 = Room.objects.create(name="Room 1", room_type=self.room_type, description="") + self.room2 = Room.objects.create(name="Room 2", room_type=self.room_type, description="") + self.customer = Customer.objects.create(name="Test", email="test@test.com", phone="123") + + def test_occupancy_zero_when_no_bookings(self): + response = self.client.get(reverse("dashboard")) + self.assertEqual(response.status_code, 200) + self.assertEqual(response.context["dashboard"]["occupancy"], 0) + + def test_occupancy_with_confirmed_bookings(self): + Booking.objects.create( + checkin=date(2025, 1, 1), checkout=date(2025, 1, 3), + room=self.room1, customer=self.customer, + guests=1, total=40, code="AAAA1111", state="NEW" + ) + response = self.client.get(reverse("dashboard")) + # 1 confirmed / 2 rooms = 50% + self.assertEqual(response.context["dashboard"]["occupancy"], 50.0) + + def test_occupancy_ignores_deleted_bookings(self): + Booking.objects.create( + checkin=date(2025, 1, 1), checkout=date(2025, 1, 3), + room=self.room1, customer=self.customer, + guests=1, total=40, code="AAAA1111", state="DEL" + ) + response = self.client.get(reverse("dashboard")) + self.assertEqual(response.context["dashboard"]["occupancy"], 0) + + def test_occupancy_100_percent(self): + Booking.objects.create( + checkin=date(2025, 1, 1), checkout=date(2025, 1, 3), + room=self.room1, customer=self.customer, + guests=1, total=40, code="AAAA1111", state="NEW" + ) + Booking.objects.create( + checkin=date(2025, 1, 1), checkout=date(2025, 1, 3), + room=self.room2, customer=self.customer, + guests=1, total=40, code="BBBB2222", state="NEW" + ) + response = self.client.get(reverse("dashboard")) + self.assertEqual(response.context["dashboard"]["occupancy"], 100.0) + + def test_occupancy_no_rooms(self): + Room.objects.all().delete() + response = self.client.get(reverse("dashboard")) + self.assertEqual(response.context["dashboard"]["occupancy"], 0) diff --git a/pms/views.py b/pms/views.py index f38563933..5303a5022 100644 --- a/pms/views.py +++ b/pms/views.py @@ -202,20 +202,25 @@ def get(self, request): .values("id") ).count() - # get outcoming guests + # get invoiced total invoiced = (Booking.objects .filter(created__range=today_range) .exclude(state="DEL") .aggregate(Sum('total')) ) + # calculate occupancy percentage + total_rooms = Room.objects.count() + confirmed_bookings = Booking.objects.filter(state="NEW").count() + occupancy = round((confirmed_bookings / total_rooms) * 100, 2) if total_rooms > 0 else 0 + # preparing context data dashboard = { 'new_bookings': new_bookings, 'incoming_guests': incoming, 'outcoming_guests': outcoming, - 'invoiced': invoiced - + 'invoiced': invoiced, + 'occupancy': occupancy, } context = {