Newer
Older
from web.utils import get_today_midnight_date
from django.contrib.auth.models import User, AnonymousUser

Carlos Vega
committed
from web.models.constants import GLOBAL_STUDY_ID, COUNTRY_OTHER_ID, AVAILABILITY_HOLIDAY, AVAILABILITY_EXTRA
Piotr Gawron
committed
from web.models.worker_study_role import STUDY_ROLE_CHOICES, HEALTH_PARTNER_ROLE_CHOICES, \
VOUCHER_PARTNER_ROLE_CHOICES, WORKER_STAFF, WORKER_HEALTH_PARTNER, WORKER_VOUCHER_PARTNER, ROLE_CHOICES
from web.utils import get_weekdays_in_period
from web.officeAvailability import OfficeAvailability
from django.db.models import Q
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
logger = logging.getLogger(__name__)
def roles_by_worker_type(worker_type):
role_choices = role_choices_by_worker_type(worker_type)
roles = []
for role_type, role_name in role_choices:
roles.append(role_type)
return roles
def role_choices_by_worker_type(worker_type):
if worker_type == WORKER_STAFF:
return STUDY_ROLE_CHOICES
elif worker_type == WORKER_HEALTH_PARTNER:
return HEALTH_PARTNER_ROLE_CHOICES
elif worker_type == WORKER_VOUCHER_PARTNER:
return VOUCHER_PARTNER_ROLE_CHOICES
else:
raise TypeError("Unknown worker type")
def worker_type_by_worker(worker):
roles = worker.roles.filter(study=GLOBAL_STUDY_ID)
if roles.count() == 0:
return WORKER_STAFF
for role_type, role_name in STUDY_ROLE_CHOICES:
if role_type == role:
return WORKER_STAFF
for role_type, role_name in HEALTH_PARTNER_ROLE_CHOICES:
if role_type == role:
return WORKER_HEALTH_PARTNER
for role_type, role_name in VOUCHER_PARTNER_ROLE_CHOICES:
if role_type == role:
return WORKER_VOUCHER_PARTNER
raise TypeError("Unknown worker role")
class Worker(models.Model):
class Meta:
app_label = 'web'
languages = models.ManyToManyField("web.Language",
verbose_name='Known languages',
blank=True
)
locations = models.ManyToManyField("web.Location",
)
user = models.OneToOneField(User, blank=True, null=True,
verbose_name='Username'
)
first_name = models.CharField(max_length=50,
verbose_name='First name',
blank=True,
)
last_name = models.CharField(max_length=50,
verbose_name='Last name',
blank=True,
name = models.CharField(max_length=50,
verbose_name='Name',
default='',
blank=True,
null=False
)
phone_number = models.CharField(max_length=20,
Piotr Gawron
committed
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
phone_number_2 = models.CharField(max_length=20,
verbose_name='Phone number 2',
blank=True
)
fax_number = models.CharField(max_length=20,
verbose_name='Fax number',
blank=True
)
address = models.CharField(max_length=255,
blank=True,
verbose_name='Address'
)
postal_code = models.CharField(max_length=7,
blank=True,
verbose_name='Postal code'
)
city = models.CharField(max_length=50,
blank=True,
verbose_name='City'
)
country = models.ForeignKey('web.Country',
null=False,
blank=False,
default=COUNTRY_OTHER_ID,
verbose_name='Country'
)
voucher_types = models.ManyToManyField("web.VoucherType",
verbose_name='Voucher types',
blank=True
)
unit = models.CharField(max_length=50,
specialization = models.CharField(max_length=20,
verbose_name='Specialization',
blank=True
Piotr Gawron
committed
voucher_partner_code = models.CharField(max_length=10,
verbose_name='Code',
blank=True
)
comment = models.TextField(max_length=1024,
verbose_name='Comment',
null=True,
blank=True
)
def is_on_leave(self):
if len(self.holiday_set.filter(datetime_end__gt=datetime.datetime.now(),

Carlos Vega
committed
datetime_start__lt=datetime.datetime.now(),
kind=AVAILABILITY_HOLIDAY)):
def disable(self):
if self.user is not None:
self.user.is_active = False
self.user.save()
logger.info("'" + self.user.username + "' account has been disabled")
return True
else:
logger.warn("Cannot disable account for user '" + self.first_name + " " + self.last_name + "'")
return False
def is_active(self):
if self.user is not None:
return self.user.is_active
else:
return False
def is_available(self, start_date=None, end_date=None):
self.availability_percentage(start_date=start_date, end_date=end_date) > 50.0
def availability_percentage(self, start_date=None, end_date=None):
'''
start_date: defaults to None and then is set to today's midnight date
end_date: defaults to None and then is set to today's midnight date + 24 hours
'''
today_midnight = get_today_midnight_date()
if start_date is None:
start_date = today_midnight
if end_date is None:
start_date = start_date.replace(hour=0, minute=0, second=0)
end_date = start_date + datetime.timedelta(days=1)

Carlos Vega
committed
office_availability = OfficeAvailability(u'{} {}'.format(self.first_name, self.last_name), start=start_date, end=end_date)

Carlos Vega
committed
#Subject Appointments
old_events = Q(date_when__gt=start_date) & Q(date_when__gt=end_date)
future_events = Q(date_when__lt=start_date) & Q(date_when__lt=end_date)
non_overlap_events = old_events | future_events
overlap_events = ~non_overlap_events
query = Q(worker=self.id) & overlap_events
subject_appointments = AppointmentTypeLink.objects.filter(query)
#General Appointments
old_events = Q(datetime_when__gt=start_date) & Q(datetime_when__gt=end_date)
future_events = Q(datetime_when__lt=start_date) & Q(datetime_when__lt=end_date)
non_overlap_events = old_events | future_events
overlap_events = ~non_overlap_events
query = Q(worker_assigned=self.id) & overlap_events
general_appointments = Appointment.objects.filter(query)
#Holidays and extra availabilities.

Carlos Vega
committed
old_events = Q(datetime_start__gt=start_date) & Q(datetime_start__gt=end_date)
future_events = Q(datetime_end__lt=start_date) & Q(datetime_end__lt=end_date)
non_overlap_events = old_events | future_events
overlap_events = ~non_overlap_events
holidays_and_extra_availabilities = self.holiday_set.filter(overlap_events).order_by('-datetime_start')
#Availability
weekdays = get_weekdays_in_period(start_date, end_date)
weekdayQ = Q() #create a filter for each weekday in the selected period
for weekday in weekdays:
weekdayQ = weekdayQ | Q(day_number=weekday)
availabilities = self.availability_set.filter(person=self.id).filter(weekdayQ).order_by('day_number', 'available_from')
things = []
things.extend(availabilities)
things.extend(holidays_and_extra_availabilities)
things.extend(subject_appointments)
things.extend(general_appointments)
for thing in things:
office_availability.consider_this(thing, only_working_hours=True)
return office_availability.get_availability_percentage(only_working_hours=True)
@property
def role(self):
roles = self.roles.filter(study=GLOBAL_STUDY_ID)
if roles.count() == 0:
return WORKER_STAFF
role = roles[0].role
if role not in [role_type for role_type, _ in ROLE_CHOICES]:
raise TypeError("Unknown worker role")
@staticmethod
def get_by_user(the_user):
if isinstance(the_user, User):
workers = Worker.objects.filter(user=the_user)
if len(workers) > 0:
return workers[0]
else:
return None
elif isinstance(the_user, Worker):
return the_user
elif isinstance(the_user, AnonymousUser):
return None
elif the_user is not None:
raise TypeError("Unknown class type: " + the_user.__class__.__name__)
else:
return None
@staticmethod
def get_workers_by_worker_type(worker_type, study_id=GLOBAL_STUDY_ID):
return Worker.objects.filter(roles__study_id=study_id,
roles__role__in=roles_by_worker_type(worker_type))
if self.name != '':
if self.first_name == '':
return self.name
else:
return "%s %s %s" % (self.name, self.first_name, self.last_name)
else:
return "%s %s" % (self.first_name, self.last_name)
if self.name != '':
if self.first_name == '':
return self.name
else:
return "%s %s %s" % (self.name, self.first_name, self.last_name)
else:
return "%s %s" % (self.first_name, self.last_name)
def initials(self):
result = ""
if len(self.first_name) > 0:
result += self.first_name[0]
if len(self.last_name) > 0:
result += self.last_name[0]
return result