From 4ebeaaf5d54c860e25f11dec7850af7e7e0a1444 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20de=20Le=C3=B3n=20Fern=C3=A1ndez?= Date: Thu, 26 Mar 2026 12:59:25 +0000 Subject: [PATCH] [ADD] Occupancy percentage widget --- pms/templates/dashboard.html | 67 +++++++++++++++++++++++------------- pms/tests.py | 58 +++++++++++++++++++++++++++++-- pms/views.py | 14 ++++++-- 3 files changed, 111 insertions(+), 28 deletions(-) diff --git a/pms/templates/dashboard.html b/pms/templates/dashboard.html index 10f0285cc..9a0ee7f86 100644 --- a/pms/templates/dashboard.html +++ b/pms/templates/dashboard.html @@ -1,27 +1,48 @@ -{% extends "main.html"%} - -{% block content %} +{% extends "main.html"%} {% block content %}

Dashboard

-
Hoy
-
-
-
Reservas hechas
-

{{dashboard.new_bookings}}

-
-
-
Huéspedes ingresando
-

{{dashboard.incoming_guests}}

-
-
-
Huéspedes saliendo
-

{{dashboard.outcoming_guests}}

-
- -
-
Total facturado
-

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

-
+
Hoy
+
+
+
Reservas hechas
+

{{dashboard.new_bookings}}

+
+
Procentaje de ocupación
+

+ {{ dashboard.occupancy_perc|floatformat:2}}% +

+
+
+
Huéspedes ingresando
+

{{dashboard.incoming_guests}}

+
+
+
Huéspedes saliendo
+

{{dashboard.outcoming_guests}}

+
+
+
Total facturado
+

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

+
+
-{% endblock content%} \ No newline at end of file +{% endblock content%} diff --git a/pms/tests.py b/pms/tests.py index 7ce503c2d..f7a5c3800 100644 --- a/pms/tests.py +++ b/pms/tests.py @@ -1,3 +1,57 @@ -from django.test import TestCase - +from django.test import TestCase, override_settings +from .models import Room, Room_type, Booking,Customer +from django.utils import timezone +from django.urls import reverse # Create your tests here. + +@override_settings(STATICFILES_STORAGE='django.contrib.staticfiles.storage.StaticFilesStorage') +class DashboardOccupancyPercentageTest(TestCase): + def setUp(self): + self.room_type = Room_type.objects.create(name='Doble', price=30, max_guests=2) + self.customer = Customer.objects.create(name="TestPerson", email="person@test.com", phone="123123123") + for i in range(4): + Room.objects.create(name=f"Room {i}", room_type=self.room_type) + + Booking.objects.create( + checkin=timezone.now().date(), + checkout=timezone.now().date(), + room=Room.objects.first(), + state="NEW", + guests=1, + customer=self.customer, + total=30, + code="R01" + ) + Booking.objects.create( + checkin=timezone.now().date(), + checkout=timezone.now().date(), + room=Room.objects.last(), + state="NEW", + guests=2, + customer=self.customer, + total=30, + code="R02" + ) + Booking.objects.create( + checkin=timezone.now().date(), + checkout=timezone.now().date(), + room=None, + state="DEL", + guests=1, + customer=self.customer, + total=0.0, + code="R03" + ) + + """Verifica que el calculo de porcentaje de ocupacion sea el correcto.""" + def test_occupancy_precentage(self): + response = self.client.get(reverse('dashboard')) + occupancy = response.context['dashboard']['occupancy_perc'] + self.assertEqual(occupancy, 50.00) + self.assertContains(response, "50.00%") + + """Verifica que no da error al dividir por 0 en caso de no existir habitaciones.""" + def test_divide_by_zero(self): + Room.objects.all().delete() + response = self.client.get(reverse('dashboard')) + self.assertEqual(response.context['dashboard']['occupancy_perc'], 0) \ No newline at end of file diff --git a/pms/views.py b/pms/views.py index f38563933..a5c00453a 100644 --- a/pms/views.py +++ b/pms/views.py @@ -6,7 +6,7 @@ from .form_dates import Ymd from .forms import * -from .models import Room +from .models import Room, Booking from .reservation_code import generate @@ -177,6 +177,7 @@ def post(self, request, pk): class DashboardView(View): def get(self, request): from datetime import date, time, datetime + today = date.today() # get bookings created today @@ -208,14 +209,21 @@ def get(self, request): .exclude(state="DEL") .aggregate(Sum('total')) ) + + # get occupancy percentage + total_rooms = Room.objects.count() + confirmed_bookings = Booking.objects.filter(checkin=today, state="NEW").count() + occupancy_perc = 0 + if total_rooms > 0: + occupancy_perc = (confirmed_bookings / total_rooms) * 100 # preparing context data dashboard = { 'new_bookings': new_bookings, 'incoming_guests': incoming, 'outcoming_guests': outcoming, - 'invoiced': invoiced - + 'invoiced': invoiced, + 'occupancy_perc': occupancy_perc } context = {