from django.core.validators import MaxValueValidator, MinValueValidator
from django.db import models
from django.utils.dates import WEEKDAYS_REV, WEEKDAYS
from django.utils.translation import ugettext_lazy as _
from django_extensions.db.models import TimeStampedModel
def add_times_by_weekday_fields(model, weekday):
"""Add fields for start and end time by week day.
"""
items = [("start", "from"), ("start", "to"),
("end", "from"), ("end", "to")]
for (start_end, from_to) in items:
# format: day_{start|end}_{from|to}_{weekday}
field_name = "day_{0}_{1}_{2}".format(start_end, from_to, weekday)
context = {
"startend": _(u"Start") if start_end == "start" else _(u"End"),
"fromto": _(u"earliest") if from_to == "from" else _(u"latest"),
"weekday": weekday,
}
# init field parameters
verbose_name = _(u"{startend} time for {weekday} ({fromto})")
verbose_name = verbose_name.format(**context)
help_text = _(u"{startend} any {weekday} at {fromto} "
u"at the given time.")
help_text = help_text.format(**context)
# create and add field
field = models.TimeField(
verbose_name=verbose_name, blank=True, null=True,
help_text=help_text)
model.add_to_class(field_name, field)
def add_dynamic_fields_for_weekdays(model):
"""Add fields dynamically for every weekday.
"""
for (weekday, idx) in WEEKDAYS_REV.items():
# add field for daily hours by week day
field_name = 'daily_hours_{0}'.format(weekday)
verbose_name = _(u"daily hours ({weekday})")
verbose_name = verbose_name.format(weekday=WEEKDAYS[idx])
help_text = _(u"Usual length of a {weekday} at work.")
help_text = help_text.format(weekday=WEEKDAYS[idx])
field = models.DecimalField(
verbose_name=verbose_name, blank=True, null=True,
max_digits=4, decimal_places=2, help_text=help_text,
validators=[MinValueValidator(0), MaxValueValidator(24)])
model.add_to_class(field_name, field)
# add fields related to time margins
add_times_by_weekday_fields(model, weekday)
TIMESHEET_INTERVAL_WEEKLY = 'weekly'
TIMESHEET_INTERVAL_BIWEEKLY = 'biweekly'
TIMESHEET_INTERVAL_MONTHLY = 'monthly'
TIMESHEET_INTERVAL_QUARTERYEARLY = 'quarteryearly'
TIMESHEET_INTERVAL_HALFYEARLY = 'halfyearly'
TIMESHEET_INTERVAL_YEARLY = 'yearly'
TIMESHEET_INTERVALS = (
(TIMESHEET_INTERVAL_WEEKLY, _(u"weekly")),
(TIMESHEET_INTERVAL_BIWEEKLY, _(u"bi-weekly")),
(TIMESHEET_INTERVAL_MONTHLY, _(u"monthly")),
(TIMESHEET_INTERVAL_QUARTERYEARLY, _(u"quarter-yearly")),
(TIMESHEET_INTERVAL_HALFYEARLY, _(u"half-yearly")),
(TIMESHEET_INTERVAL_YEARLY, _(u"yearly")),
)
[docs]class TimeModel(TimeStampedModel):
"""Set of "rules" for employee working hours.
"""
workdays_per_week = models.SmallIntegerField(
verbose_name=_(u"workdays per week"),
default=5, blank=True, null=True,
validators=[MinValueValidator(0), MaxValueValidator(7)],
help_text=_(u"Number of workdays in a usual work-week."))
daily_hours = models.DecimalField(
verbose_name=_(u"daily hours"), blank=True, null=True,
max_digits=4, decimal_places=2,
validators=[MinValueValidator(0), MaxValueValidator(24)],
help_text=_(u"Usual length of a workday."))
weekly_hours = models.DecimalField(
verbose_name=_(u"weekly hours"), blank=True, null=True,
max_digits=5, decimal_places=2,
validators=[MinValueValidator(0), MaxValueValidator(168)],
help_text=_(u"Usual length of a work week."))
yearly_vacation = models.IntegerField(
verbose_name=_(u"yearly vacation quota"), default=25,
help_text=_(u"Vacation quota valid in the TimeSheet's period."))
timesheet_interval = models.CharField(
verbose_name=_(u"timesheet interval"), choices=TIMESHEET_INTERVALS,
max_length=20, default=TIMESHEET_INTERVAL_MONTHLY)
day_start_from = models.TimeField(
verbose_name=_(u"Daily start time (from)"), blank=True, null=True,
help_text=_(u"Start every day at earliest at the given time."))
day_start_to = models.TimeField(
verbose_name=_(u"Daily start time (to)"), blank=True, null=True,
help_text=_(u"Start every day at latest at the given time."))
day_end_from = models.TimeField(
verbose_name=_(u"Daily end time (from)"), blank=True, null=True,
help_text=_(u"End every day at earliest at the given time."))
day_end_to = models.TimeField(
verbose_name=_(u"Daily end time (to)"), blank=True, null=True,
help_text=_(u"End every day at latest at the given time."))
class Meta:
app_label = 'sandglass'
# add dynamic field definitions for weekdays to time model
add_dynamic_fields_for_weekdays(TimeModel)
__all__ = ('TimeModel',)