Generated: Sun 2013-03-24 21:11 CET
Source file: /home/tobi/Projects/calendarium/src/calendarium/forms.py
Stats: 52 executed, 12 missed, 6 excluded, 57 ignored
"""Forms for the ``calendarium`` app."""
from django import forms
from django.contrib.auth.models import User
from django.forms.models import model_to_dict
from django.utils.timezone import datetime, timedelta
from calendarium.constants import (
OCCURRENCE_DECISION_CHOICESS,
OCCURRENCE_DECISIONS,
)
from calendarium.models import Event, Occurrence
class OccurrenceForm(forms.ModelForm):
"""A form for the ``Occurrence`` model."""
decision = forms.CharField(
widget=forms.Select(choices=OCCURRENCE_DECISION_CHOICESS),
)
cancelled = forms.BooleanField(
widget=forms.HiddenInput,
required=False,
)
original_start = forms.DateTimeField(
widget=forms.HiddenInput,
)
original_end = forms.DateTimeField(
widget=forms.HiddenInput,
)
event = forms.ModelChoiceField(
widget=forms.HiddenInput,
queryset=Event.objects.all(),
)
class Meta:
model = Occurrence
def save(self):
cleaned_data = self.cleaned_data
if cleaned_data['decision'] == OCCURRENCE_DECISIONS['all']:
changes = {
key: value for key, value in cleaned_data.iteritems()
if value != self.initial.get(key) and self.initial.get(key)}
event = self.instance.event
# for each field on the event, check for new data in cleaned_data
for field_name in [field.name for field in event._meta.fields]:
value = changes.get(field_name)
if value:
setattr(event, field_name, value)
event.save()
# repeat for persistent occurrences
for occ in event.occurrences.all():
for field_name in [field.name for field in occ._meta.fields]:
value = changes.get(field_name)
if value:
# since we can't just set a new datetime, we have to
# adjust the datetime fields according to the changes
# on the occurrence form instance
if type(value) != datetime:
setattr(occ, field_name, value)
else:
initial_time = self.initial.get(field_name)
occ_time = getattr(occ, field_name)
delta = value - initial_time
new_time = occ_time + delta
setattr(occ, field_name, new_time)
occ.save()
# get everything from initial and compare to cleaned_data to
# retrieve what has been changed
# apply those changes to the persistent occurrences (and the main
# event)
elif cleaned_data['decision'] == OCCURRENCE_DECISIONS['this one']:
self.instance.save()
elif cleaned_data['decision'] == OCCURRENCE_DECISIONS['following']:
# get the changes
changes = {
key: value for key, value in cleaned_data.iteritems()
if value != self.initial.get(key) and self.initial.get(key)}
# change the old event
old_event = self.instance.event
end_recurring_period = self.instance.event.end_recurring_period
old_event.end_recurring_period = self.instance.start - timedelta(
days=1)
old_event.save()
# the instance occurrence holds the info for the new event, that we
# use to update the old event's fields
new_event = old_event
new_event.end_recurring_period = end_recurring_period
new_event.id = None
event_kwargs = model_to_dict(self.instance)
for field_name in [field.name for field in new_event._meta.fields]:
if field_name == 'created_by':
value = User.objects.get(pk=event_kwargs.get(field_name))
elif field_name in ['rule', 'category']:
continue
else:
value = event_kwargs.get(field_name)
if value:
setattr(new_event, field_name, value)
new_event.save()
# update the new event and update all of the corresponding occs
for occ in self.instance.event.occurrences.filter(
start__gte=self.instance.start):
occ.event = new_event
for field_name in [field.name for field in occ._meta.fields]:
value = changes.get(field_name)
if value:
# since we can't just set a new datetime, we have to
# adjust the datetime fields according to the changes
# on the occurrence form instance
if type(value) != datetime:
setattr(occ, field_name, value)
else:
initial_time = self.initial.get(field_name)
occ_time = getattr(occ, field_name)
delta = value - initial_time
new_time = occ_time + delta
setattr(occ, field_name, new_time)
occ.save()