Newer
Older

Carlos Vega
committed
# coding=utf-8
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)
first_name = u'âêîôûŵŷäëïöüẅÿà'
last_name = u'èìòùẁỳáéíóúẃýćńóśźżąę'
office_availability = OfficeAvailability(u'{} {}'.format(first_name, last_name),
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
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)