__copyright__ = "Copyright © Stichting SciPost (SciPost Foundation)"
__license__ = "AGPL v3"
import datetime
from django import forms
from django.contrib.auth import get_user_model
from django.utils.dates import MONTHS
from django.db.models import Sum
from django.utils import timezone
from dal import autocomplete
from dateutil.rrule import rrule, MONTHLY
from common.forms import MonthYearWidget
from organizations.models import Organization
from scipost.fields import UserModelChoiceField
from .models import Subsidy, SubsidyAttachment, WorkLog
#############
# Work logs #
#############
[docs]class LogsFilter(forms.Form):
"""
Filter work logs given the requested date range and users.
"""
employee = UserModelChoiceField(
queryset=get_user_model().objects.filter(work_logs__isnull=False).distinct(),
required=False, empty_label='Show all')
start = forms.DateField(widget=MonthYearWidget(required=True), required=True) # Month
end = forms.DateField(widget=MonthYearWidget(required=True, end=True), required=True) # Month
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
today = timezone.now().date()
self.initial['start'] = today.today()
self.initial['end'] = today.today()
[docs] def clean(self):
if self.is_valid():
self.cleaned_data['months'] = [
dt for dt in rrule(
MONTHLY,
dtstart=self.cleaned_data['start'],
until=self.cleaned_data['end'])]
return self.cleaned_data
[docs] def get_months(self):
if self.is_valid():
return self.cleaned_data.get('months', [])
return []
[docs] def filter(self):
"""Filter work logs and return in user-grouped format."""
output = []
if self.is_valid():
if self.cleaned_data['employee']:
user_qs = get_user_model().objects.filter(id=self.cleaned_data['employee'].id)
else:
user_qs = get_user_model().objects.filter(work_logs__isnull=False)
user_qs = user_qs.filter(
work_logs__work_date__gte=self.cleaned_data['start'],
work_logs__work_date__lte=self.cleaned_data['end']).distinct()
output = []
for user in user_qs:
logs = user.work_logs.filter(
work_date__gte=self.cleaned_data['start'],
work_date__lte=self.cleaned_data['end']).distinct()
output.append({
'logs': logs,
'duration': logs.aggregate(total=Sum('duration')),
'user': user,
})
return output
[docs] def filter_per_month(self):
"""Filter work logs and return in per-month format."""
output = []
if self.is_valid():
if self.cleaned_data['employee']:
user_qs = get_user_model().objects.filter(id=self.cleaned_data['employee'].id)
else:
user_qs = get_user_model().objects.filter(work_logs__isnull=False)
user_qs = user_qs.filter(
work_logs__work_date__gte=self.cleaned_data['start'],
work_logs__work_date__lte=self.cleaned_data['end']).distinct()
output = []
for user in user_qs:
# If logs exists for given filters
output.append({
'logs': [],
'user': user,
})
for dt in self.get_months():
output[-1]['logs'].append(
user.work_logs.filter(
work_date__year=dt.year, work_date__month=dt.month).aggregate(total=Sum('duration'))['total'])
return output