diff --git a/dav_events/migrations/0034_eventchange.py b/dav_events/migrations/0034_eventchange.py index e83f74b..a185f07 100644 --- a/dav_events/migrations/0034_eventchange.py +++ b/dav_events/migrations/0034_eventchange.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Generated by Django 1.11.29 on 2020-09-29 10:11 +# Generated by Django 1.11.29 on 2020-09-29 20:15 from __future__ import unicode_literals import dav_events.models.eventchange @@ -23,7 +23,7 @@ class Migration(migrations.Migration): fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('timestamp', models.DateTimeField(default=django.utils.timezone.now)), - ('operation', models.CharField(choices=[('update', 'update')], max_length=20)), + ('operation', models.CharField(choices=[('update', 'Update'), ('set_flag', 'Raise Flag'), ('unset_flag', 'Lower Flag')], max_length=20)), ('content', models.TextField()), ('event', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='changes', to='dav_events.Event')), ('user', models.ForeignKey(default=dav_events.models.eventchange.get_system_user_id, on_delete=models.SET(dav_events.roles.get_ghost_user), related_name='+', to=settings.AUTH_USER_MODEL)), diff --git a/dav_events/models/event.py b/dav_events/models/event.py index b3ae952..c4c3b0c 100644 --- a/dav_events/models/event.py +++ b/dav_events/models/event.py @@ -306,11 +306,13 @@ class Event(models.Model): signals.event_created.send(sender=self.__class__, event=self) self.workflow.update_status('draft', self.editor) else: - change = EventChange(event=self, user=self.editor, operation='update', content=self.diff(original)) + change = EventChange(event=self, user=self.editor, operation=EventChange.UPDATE, + content=self.diff(original)) change.save() if not implicit_update: logger.info('Event updated: %s', self) - signals.event_updated.send(sender=self.__class__, event=self, diff=self.diff(original, fmt='human_readable'), user=self.editor) + signals.event_updated.send(sender=self.__class__, event=self, user=self.editor, + diff=self.diff(original, fmt='human_readable')) def diff(self, event, fmt='json'): if fmt == 'human_readable': @@ -326,16 +328,14 @@ class Event(models.Model): for field in fields: field_name = field.name from_value = getattr(event, field_name) - if (isinstance(from_value, datetime.datetime) or - isinstance(from_value, datetime.date) or - isinstance(from_value, datetime.time) or - isinstance(from_value, Country)): + try: + json.dumps(from_value) + except TypeError: from_value = str(from_value) to_value = getattr(self, field_name) - if (isinstance(to_value, datetime.datetime) or - isinstance(to_value, datetime.date) or - isinstance(to_value, datetime.time) or - isinstance(to_value, Country)): + try: + json.dumps(to_value) + except TypeError: to_value = str(to_value) if from_value != to_value: change = { diff --git a/dav_events/models/eventchange.py b/dav_events/models/eventchange.py index 0d0f14d..a1f3084 100644 --- a/dav_events/models/eventchange.py +++ b/dav_events/models/eventchange.py @@ -7,10 +7,6 @@ from django.utils.encoding import python_2_unicode_compatible from . import get_ghost_user, get_system_user -CHANGE_OPERATIONS = ( - ('update', 'update'), -) - def get_system_user_id(): return get_system_user().id @@ -18,6 +14,15 @@ def get_system_user_id(): @python_2_unicode_compatible class EventChange(models.Model): + UPDATE = 'update' + RAISE_FLAG = 'set_flag' + LOWER_FLAG = 'unset_flag' + OPERATION_CHOICES = ( + (UPDATE, 'Update'), + (RAISE_FLAG, 'Raise Flag'), + (LOWER_FLAG, 'Lower Flag'), + ) + event = models.ForeignKey('dav_events.Event', related_name='changes') timestamp = models.DateTimeField(default=timezone.now) user = models.ForeignKey(settings.AUTH_USER_MODEL, @@ -25,7 +30,7 @@ class EventChange(models.Model): on_delete=models.SET(get_ghost_user), related_name='+') - operation = models.CharField(max_length=20, choices=CHANGE_OPERATIONS) + operation = models.CharField(max_length=20, choices=OPERATION_CHOICES) content = models.TextField() class Meta: diff --git a/dav_events/templatetags/dav_events.py b/dav_events/templatetags/dav_events.py index b63b81e..4449da5 100644 --- a/dav_events/templatetags/dav_events.py +++ b/dav_events/templatetags/dav_events.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- import json from django import template from django.utils.html import format_html @@ -5,6 +6,7 @@ from django.utils.safestring import mark_safe from django.utils import timezone from django.utils.translation import ugettext as _ +from ..models.eventchange import EventChange from ..models.eventstatus import EventStatus, get_or_create_event_status register = template.Library() @@ -38,50 +40,81 @@ def render_event_status(event, show_void=True): @register.simple_tag def render_event_changelog(event): change_templ = u'
  • \n' \ - u'\t

    {timestamp}' \ + u'\t

    ' \ + u'' \ + u' {timestamp}' \ u' - ' \ u' {user}

    \n' \ u'\t{content}\n' \ u'
  • \n' - subchange_templ = u'
  • \n' \ - u'\t{field}:{separator1}\n' \ - u'\t{refer}\n' \ - u'\t{separator2}\n' \ - u'\t{current}\n' \ - u'
  • \n' + update_sub_templ = u'
  • \n' \ + u'\t{field}:{separator1}\n' \ + u'\t{refer}\n' \ + u'\t{separator2}\n' \ + u'\t{current}\n' \ + u'
  • \n' + raise_flag_templ = u'' \ + u' {label}' \ + u' ' + lower_flag_templ = u'' \ + u' {label}' \ + u' ' if event.changes.exists(): html = u'\n' else: - html = _(u'No entries') + html = _(u'Keine Einträge') return mark_safe(html) diff --git a/dav_events/tests/test_models.py b/dav_events/tests/test_models.py index 9899fdf..48c0c65 100644 --- a/dav_events/tests/test_models.py +++ b/dav_events/tests/test_models.py @@ -4,6 +4,7 @@ import datetime import json from django.test import TestCase +from ..models.eventchange import EventChange from .generic import EventMixin TEST_EVENT_DATA = { @@ -21,12 +22,6 @@ TEST_EVENT_DATA = { class EventsTestCase(EventMixin, TestCase): - def test_empty_changelog(self): - data = TEST_EVENT_DATA - event = self.create_event_by_model(data) - event.sport = 'M' - self.assertFalse(event.changes.exists()) - def test_changelog(self): data = TEST_EVENT_DATA event = self.create_event_by_model(data) @@ -44,19 +39,29 @@ class EventsTestCase(EventMixin, TestCase): event.save() changes = event.changes - self.assertEqual(changes.count(), 3) + self.assertEqual(changes.count(), 4) - subchanges = json.loads(changes.get(pk=1).content) + change = changes.get(pk=1) + self.assertEqual(change.operation, EventChange.RAISE_FLAG) + self.assertEqual(change.content, 'draft') + + change = changes.get(pk=2) + self.assertEqual(change.operation, EventChange.UPDATE) + subchanges = json.loads(change.content) self.assertEqual(len(subchanges), 3) self.assertIn({'field': 'alt_first_day', 'refer': None, 'current': '2019-03-02'}, subchanges) self.assertIn({'field': 'sport', 'refer': 'W', 'current': 'M'}, subchanges) self.assertIn({'field': 'ski_lift', 'refer': False, 'current': True}, subchanges) - subchanges = json.loads(changes.get(pk=2).content) + change = changes.get(pk=3) + self.assertEqual(change.operation, EventChange.UPDATE) + subchanges = json.loads(change.content) self.assertEqual(len(subchanges), 1) self.assertIn({'field': 'country', 'refer': 'DE', 'current': 'FR'}, subchanges) - subchanges = json.loads(changes.get(pk=3).content) + change = changes.get(pk=4) + self.assertEqual(change.operation, EventChange.UPDATE) + subchanges = json.loads(change.content) self.assertEqual(len(subchanges), 2) self.assertIn({'field': 'trainer_familyname', 'refer': 'Weißalles', 'current': 'Weißalles-Ömlaut'}, subchanges) self.assertIn({'field': 'max_participants', 'refer': 0, 'current': 8}, subchanges) diff --git a/dav_events/workflow.py b/dav_events/workflow.py index 8538882..1856480 100644 --- a/dav_events/workflow.py +++ b/dav_events/workflow.py @@ -9,6 +9,7 @@ from django.utils.translation import ugettext_lazy as _ from . import emails from . import signals +from .models.eventchange import EventChange from .models.eventflag import EventFlag from .models.eventstatus import get_or_create_event_status from .roles import get_users_by_role, has_role @@ -50,6 +51,8 @@ class BasicWorkflow(object): kwargs['status'] = status flag = EventFlag(**kwargs) flag.save() + change = EventChange(event=event, user=flag.user, operation=EventChange.RAISE_FLAG, content=status.code) + change.save() logger.info('Flagging status \'%s\' for %s', status.code, event) return flag