calendarium.forms: 70 total statements, 81.2% covered

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

  1. """Forms for the ``calendarium`` app."""
  2. from django import forms
  3. from django.contrib.auth.models import User
  4. from django.forms.models import model_to_dict
  5. from django.utils.timezone import datetime, timedelta
  6. from calendarium.constants import (
  7. OCCURRENCE_DECISION_CHOICESS,
  8. OCCURRENCE_DECISIONS,
  9. )
  10. from calendarium.models import Event, Occurrence
  11. class OccurrenceForm(forms.ModelForm):
  12. """A form for the ``Occurrence`` model."""
  13. decision = forms.CharField(
  14. widget=forms.Select(choices=OCCURRENCE_DECISION_CHOICESS),
  15. )
  16. cancelled = forms.BooleanField(
  17. widget=forms.HiddenInput,
  18. required=False,
  19. )
  20. original_start = forms.DateTimeField(
  21. widget=forms.HiddenInput,
  22. )
  23. original_end = forms.DateTimeField(
  24. widget=forms.HiddenInput,
  25. )
  26. event = forms.ModelChoiceField(
  27. widget=forms.HiddenInput,
  28. queryset=Event.objects.all(),
  29. )
  30. class Meta:
  31. model = Occurrence
  32. def save(self):
  33. cleaned_data = self.cleaned_data
  34. if cleaned_data['decision'] == OCCURRENCE_DECISIONS['all']:
  35. changes = {
  36. key: value for key, value in cleaned_data.iteritems()
  37. if value != self.initial.get(key) and self.initial.get(key)}
  38. event = self.instance.event
  39. # for each field on the event, check for new data in cleaned_data
  40. for field_name in [field.name for field in event._meta.fields]:
  41. value = changes.get(field_name)
  42. if value:
  43. setattr(event, field_name, value)
  44. event.save()
  45. # repeat for persistent occurrences
  46. for occ in event.occurrences.all():
  47. for field_name in [field.name for field in occ._meta.fields]:
  48. value = changes.get(field_name)
  49. if value:
  50. # since we can't just set a new datetime, we have to
  51. # adjust the datetime fields according to the changes
  52. # on the occurrence form instance
  53. if type(value) != datetime:
  54. setattr(occ, field_name, value)
  55. else:
  56. initial_time = self.initial.get(field_name)
  57. occ_time = getattr(occ, field_name)
  58. delta = value - initial_time
  59. new_time = occ_time + delta
  60. setattr(occ, field_name, new_time)
  61. occ.save()
  62. # get everything from initial and compare to cleaned_data to
  63. # retrieve what has been changed
  64. # apply those changes to the persistent occurrences (and the main
  65. # event)
  66. elif cleaned_data['decision'] == OCCURRENCE_DECISIONS['this one']:
  67. self.instance.save()
  68. elif cleaned_data['decision'] == OCCURRENCE_DECISIONS['following']:
  69. # get the changes
  70. changes = {
  71. key: value for key, value in cleaned_data.iteritems()
  72. if value != self.initial.get(key) and self.initial.get(key)}
  73. # change the old event
  74. old_event = self.instance.event
  75. end_recurring_period = self.instance.event.end_recurring_period
  76. old_event.end_recurring_period = self.instance.start - timedelta(
  77. days=1)
  78. old_event.save()
  79. # the instance occurrence holds the info for the new event, that we
  80. # use to update the old event's fields
  81. new_event = old_event
  82. new_event.end_recurring_period = end_recurring_period
  83. new_event.id = None
  84. event_kwargs = model_to_dict(self.instance)
  85. for field_name in [field.name for field in new_event._meta.fields]:
  86. if field_name == 'created_by':
  87. value = User.objects.get(pk=event_kwargs.get(field_name))
  88. elif field_name in ['rule', 'category']:
  89. continue
  90. else:
  91. value = event_kwargs.get(field_name)
  92. if value:
  93. setattr(new_event, field_name, value)
  94. new_event.save()
  95. # update the new event and update all of the corresponding occs
  96. for occ in self.instance.event.occurrences.filter(
  97. start__gte=self.instance.start):
  98. occ.event = new_event
  99. for field_name in [field.name for field in occ._meta.fields]:
  100. value = changes.get(field_name)
  101. if value:
  102. # since we can't just set a new datetime, we have to
  103. # adjust the datetime fields according to the changes
  104. # on the occurrence form instance
  105. if type(value) != datetime:
  106. setattr(occ, field_name, value)
  107. else:
  108. initial_time = self.initial.get(field_name)
  109. occ_time = getattr(occ, field_name)
  110. delta = value - initial_time
  111. new_time = occ_time + delta
  112. setattr(occ, field_name, new_time)
  113. occ.save()