Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion pms/templates/dashboard.html
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ <h1 class="dashboard-value">{{dashboard.outcoming_guests}}</h1>
<h5 class="small">Total facturado</h5>
<h1 class="dashboard-value">€ {% if dashboard.invoiced.total__sum == None %}0.00{% endif %} {{dashboard.invoiced.total__sum|floatformat:2}}</h1>
</div>
<div class="card text-white p-3 card-customization" style="background-color: #6f42c1;">
<h5 class="small">% Ocupación</h5>
<h1 class="dashboard-value">{{dashboard.occupancy_percentage}}%</h1>
</div>
</div>
</div>
{% endblock content%}
{% endblock content%}
103 changes: 101 additions & 2 deletions pms/tests.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,102 @@
from django.test import TestCase
from datetime import date

# Create your tests here.
from django.test import TestCase, override_settings
from django.urls import reverse

from .models import Booking, Customer, Room, Room_type


@override_settings(STATICFILES_STORAGE="django.contrib.staticfiles.storage.StaticFilesStorage")
class DashboardViewTests(TestCase):
@classmethod
def setUpTestData(cls):
cls.dashboard_url = reverse("dashboard")

cls.room_type = Room_type.objects.create(
name="Double",
price=30,
max_guests=2,
)

cls.room_one = Room.objects.create(
room_type=cls.room_type,
name="Room 1.1",
)
cls.room_two = Room.objects.create(
room_type=cls.room_type,
name="Room 1.2",
)
cls.room_three = Room.objects.create(
room_type=cls.room_type,
name="Room 1.3",
)

cls.customer = Customer.objects.create(
name="John Doe",
email="john@example.com",
phone="123456789",
)

def create_booking(self, room, state=Booking.NEW, total=60, code=None):
return Booking.objects.create(
state=state,
checkin=date.today(),
checkout=date.today(),
room=room,
guests=1,
customer=self.customer,
total=total,
code=code or f"CODE{Booking.objects.count() + 1:04d}",
)

def test_dashboard_renders_occupancy_widget(self):
response = self.client.get(self.dashboard_url)

self.assertEqual(response.status_code, 200)
self.assertContains(response, "% Ocupación")
self.assertEqual(response.context["dashboard"]["occupancy_percentage"], 0)

def test_dashboard_calculates_occupancy_percentage_from_active_bookings(self):
self.create_booking(room=self.room_one, state=Booking.NEW)
self.create_booking(room=self.room_two, state=Booking.NEW)

response = self.client.get(self.dashboard_url)

self.assertEqual(response.status_code, 200)
self.assertAlmostEqual(
response.context["dashboard"]["occupancy_percentage"],
66.7,
places=1,
)
self.assertContains(response, "66.7%")

def test_dashboard_excludes_deleted_bookings_from_occupancy_percentage(self):
self.create_booking(room=self.room_one, state=Booking.NEW)
self.create_booking(room=self.room_two, state=Booking.DELETED)

response = self.client.get(self.dashboard_url)

self.assertEqual(response.status_code, 200)
self.assertAlmostEqual(
response.context["dashboard"]["occupancy_percentage"],
33.3,
places=1,
)
self.assertContains(response, "33.3%")

def test_dashboard_excludes_deleted_bookings_from_new_bookings_count(self):
self.create_booking(room=self.room_one, state=Booking.NEW)
self.create_booking(room=self.room_two, state=Booking.DELETED)

response = self.client.get(self.dashboard_url)

self.assertEqual(response.status_code, 200)
self.assertEqual(response.context["dashboard"]["new_bookings"], 1)

def test_dashboard_sets_zero_occupancy_when_there_are_no_rooms(self):
Room.objects.all().delete()

response = self.client.get(self.dashboard_url)

self.assertEqual(response.status_code, 200)
self.assertEqual(response.context["dashboard"]["occupancy_percentage"], 0)
39 changes: 24 additions & 15 deletions pms/views.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from datetime import date, time, datetime

from django.db.models import F, Q, Count, Sum
from django.shortcuts import render, redirect
from django.utils.decorators import method_decorator
Expand All @@ -6,7 +8,7 @@

from .form_dates import Ymd
from .forms import *
from .models import Room
from .models import Room, Booking
from .reservation_code import generate


Expand Down Expand Up @@ -176,7 +178,6 @@ 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
Expand All @@ -185,45 +186,53 @@ def get(self, request):
today_range = (today_min, today_max)
new_bookings = (Booking.objects
.filter(created__range=today_range)
.values("id")
).count()
.exclude(state=Booking.DELETED)
.count()
)

# get incoming guests
incoming = (Booking.objects
.filter(checkin=today)
.exclude(state="DEL")
.values("id")
).count()
.exclude(state=Booking.DELETED)
.count()
)

# get outcoming guests
outcoming = (Booking.objects
.filter(checkout=today)
.exclude(state="DEL")
.values("id")
).count()
.exclude(state=Booking.DELETED)
.count()
)

# get outcoming guests
# get invoiced total
invoiced = (Booking.objects
.filter(created__range=today_range)
.exclude(state="DEL")
.exclude(state=Booking.DELETED)
.aggregate(Sum('total'))
)

# get occupancy percentage
total_rooms = Room.objects.count()
confirmed_bookings = Booking.objects.filter(state=Booking.NEW).count()
occupancy_percentage = (
round((confirmed_bookings / total_rooms) * 100, 1)
if total_rooms else 0
)

# preparing context data
dashboard = {
'new_bookings': new_bookings,
'incoming_guests': incoming,
'outcoming_guests': outcoming,
'invoiced': invoiced

'invoiced': invoiced,
'occupancy_percentage': occupancy_percentage,
}

context = {
'dashboard': dashboard
}
return render(request, "dashboard.html", context)


class RoomDetailsView(View):
def get(self, request, pk):
# renders room details
Expand Down