diff --git a/smash/web/tests/test_office_availability.py b/smash/web/tests/test_office_availability.py new file mode 100644 index 0000000000000000000000000000000000000000..b1184285f2c0c768d27ce8874f3cf776f474f9d0 --- /dev/null +++ b/smash/web/tests/test_office_availability.py @@ -0,0 +1,113 @@ +import logging + +from django.test import TestCase +from django.utils import timezone +import datetime +import pandas as pd +from datetime import timedelta +from functions import create_availability, create_visit, create_appointment, create_appointment_type +from web.utils import get_weekdays_in_period +from web.officeAvailability import OfficeAvailability +from web.models.holiday import Holiday +from web.models.availability import Availability +from web.models.appointment import Appointment +from web.models.appointment_type_link import AppointmentTypeLink +from web.models.constants import AVAILABILITY_HOLIDAY, AVAILABILITY_EXTRA +from web.tests.functions import create_worker + +logger = logging.getLogger(__name__) + +class OfficeAvailabilityTest(TestCase): + def test_availability_cases(self): + # + today = timezone.now() + start_date = datetime.datetime(today.year, today.month, today.day, tzinfo=today.tzinfo) #today midnight + end_date = start_date + datetime.timedelta(days=1) + + office_availability = OfficeAvailability('FirstName LastName', + start=start_date, end=end_date, office_start='8:00', office_end='18:00') + + #no availabilties added yet + self.assertEqual(office_availability.is_available(), False) + self.assertEqual(office_availability.is_available(only_working_hours=True), False) + self.assertEqual(office_availability.get_availability_percentage(only_working_hours=True), 0.0) + self.assertEqual(office_availability.get_availability_percentage(only_working_hours=False), 0.0) + + #add availabilty from 8:00 to 18:00 + weekday = list(get_weekdays_in_period(start_date, end_date))[0] + availability = create_availability(available_from='8:00', available_till='18:00', day_number=weekday) + office_availability.consider_this(availability) + self.assertEqual(office_availability.is_available(only_working_hours=True), True) + self.assertEqual(office_availability.is_available(), False) #less than 50% + self.assertEqual(office_availability.get_availability_percentage(only_working_hours=True), 100.0) + self.assertEqual(office_availability.get_availability_percentage(only_working_hours=False), 41.70714781401804) # ((10*(60)+1)/(24*60.0+1))*100 That +1 is the zero minute + + #add holiday from 16:00 to 18:00 # 2 hours less availability + start_date = datetime.datetime(today.year, today.month, today.day, 16, 00, tzinfo=today.tzinfo) + end_date = start_date + datetime.timedelta(hours=2) + holiday = Holiday(person=create_worker(), datetime_start=start_date, datetime_end=end_date, kind=AVAILABILITY_HOLIDAY) + office_availability.consider_this(holiday) + self.assertEqual(office_availability.is_available(only_working_hours=True), True) + self.assertEqual(office_availability.is_available(), False) #less than 50% + self.assertEqual(office_availability.get_availability_percentage(only_working_hours=True), 79.86688851913478) # ((8*60)/(10*60.0+1))*100 # the bordwer minute is 0, then no +1 + self.assertEqual(office_availability.get_availability_percentage(only_working_hours=False), 33.31020124913255) # ((8*60)/(24*60.0+1))*100 + + #add extra availability from 17:00 to 18:00 # 1 hour more availability + start_date = datetime.datetime(today.year, today.month, today.day, 17, 00, tzinfo=today.tzinfo) + end_date = start_date + datetime.timedelta(hours=1) + extra_availability = Holiday(person=create_worker(), datetime_start=start_date, datetime_end=end_date, kind=AVAILABILITY_EXTRA) + office_availability.consider_this(extra_availability) + self.assertEqual(office_availability.is_available(only_working_hours=True), True) + self.assertEqual(office_availability.is_available(), False) #less than 50% + self.assertEqual(office_availability.get_availability_percentage(only_working_hours=True), 90.01663893510815) # ((9*60+1)/(10*60.0+1))*100 # the border minute is now 1 then +1 + self.assertEqual(office_availability.get_availability_percentage(only_working_hours=False), 37.543372657876475) + + #add appointment from 9:00 to 10:00 # 1 hour less availability + #create visit + visit_start_date = start_date - datetime.timedelta(days=31) + visit_end_date = end_date + datetime.timedelta(days=31) + visit = create_visit(subject=None, datetime_begin=visit_start_date, datetime_end=visit_end_date) + #create appointment + appointment_typeA = create_appointment_type(code='A', default_duration=40, description='test1') + appointment_typeB = create_appointment_type(code='B', default_duration=20, description='test2') + appointment_when = datetime.datetime(today.year, today.month, today.day, 9, 00, tzinfo=today.tzinfo) + appointment = create_appointment(visit=visit, when=appointment_when, length=60) + worker = create_worker() + app_type_linkA = AppointmentTypeLink(appointment=appointment, date_when=appointment_when, appointment_type=appointment_typeA, worker=worker) + app_type_linkB = AppointmentTypeLink(appointment=appointment, date_when=appointment_when+datetime.timedelta(minutes=20), appointment_type=appointment_typeB, worker=worker) + appointment.save() + #the availability percentage should be the same as before adding the extra availability + office_availability.consider_this(appointment) + self.assertEqual(office_availability.is_available(only_working_hours=True), True) + self.assertEqual(office_availability.is_available(), False) #less than 50% + self.assertEqual(office_availability.get_availability_percentage(only_working_hours=True), 79.86688851913478) # ((8*60)/(10*60.0+1))*100 # the bordwer minute is 0, then no +1 + self.assertEqual(office_availability.get_availability_percentage(only_working_hours=False), 33.31020124913255) # ((8*60)/(24*60.0+1))*100 + #consider the 2 AppointmentTypeLinks. The availability percentage shouldn't change + office_availability.consider_this(app_type_linkA) + office_availability.consider_this(app_type_linkB) + self.assertEqual(office_availability.is_available(only_working_hours=True), True) + self.assertEqual(office_availability.is_available(), False) #less than 50% + self.assertEqual(office_availability.get_availability_percentage(only_working_hours=True), 79.86688851913478) # ((8*60)/(10*60.0+1))*100 # the bordwer minute is 0, then no +1 + self.assertEqual(office_availability.get_availability_percentage(only_working_hours=False), 33.31020124913255) # ((8*60)/(24*60.0+1))*100 + + #force add availability from 9:00 to 10:00 # 1 hour more availability + start_date = datetime.datetime(today.year, today.month, today.day, 9, 00, tzinfo=today.tzinfo).replace(second=0, microsecond=0) + end_date = start_date + datetime.timedelta(hours=1) + office_availability.add_availability(pd.date_range(start=start_date, end=end_date, freq='1T'), only_working_hours=False) + self.assertEqual(office_availability.is_available(only_working_hours=True), True) + self.assertEqual(office_availability.is_available(), False) #less than 50% + self.assertEqual(office_availability.get_availability_percentage(only_working_hours=True), 90.01663893510815) # ((9*60+1)/(10*60.0+1))*100 # the border minute is now 1 then +1 + self.assertEqual(office_availability.get_availability_percentage(only_working_hours=False), 37.543372657876475) + + #force remove availability from 9:00 to 12:00 # 3 hour less availability + start_date = datetime.datetime(today.year, today.month, today.day, 9, 00, tzinfo=today.tzinfo).replace(second=0, microsecond=0) + end_date = start_date + datetime.timedelta(hours=3) + office_availability.remove_availability(pd.date_range(start=start_date, end=end_date, freq='1T'), only_working_hours=True) + self.assertEqual(office_availability.is_available(only_working_hours=True), True) + self.assertEqual(office_availability.is_available(), False) #less than 50% + self.assertEqual(office_availability.get_availability_percentage(only_working_hours=True), 59.900166389351085) # ((6*60)/(10*60.0+1))*100 # the border minute is 0 then no +1 + self.assertEqual(office_availability.get_availability_percentage(only_working_hours=False), 24.98265093684941) + + + +