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'
+
for change in event.changes.all():
+
username = change.user.get_full_name()
if not username:
username = change.user
- content_html = u''
- subchanges = json.loads(change.content)
- for subchange in subchanges:
- field_label = event._meta.get_field(subchange['field']).verbose_name
- try:
- is_long_strings = (len(subchange['refer']) + len(subchange['current'])) > 20
- except TypeError:
- is_long_strings = False
- if is_long_strings:
- separator1 = u'
'
- separator2 = u'
'
- else:
- separator1 = u' '
- separator2 = u' -> '
- content_html += format_html(subchange_templ,
- field=field_label,
- separator1=mark_safe(separator1),
- refer=subchange['refer'],
- separator2=mark_safe(separator2),
- current=subchange['current'])
- content_html += u'
'
+
+ if change.operation == EventChange.UPDATE:
+ icon = u'pencil'
+ content_html = u''
+ subchanges = json.loads(change.content)
+ for subchange in subchanges:
+ field_label = event._meta.get_field(subchange['field']).verbose_name
+ try:
+ is_long_strings = (len(subchange['refer']) + len(subchange['current'])) > 20
+ except TypeError:
+ is_long_strings = False
+ if is_long_strings:
+ separator1 = u'
'
+ separator2 = u'
'
+ else:
+ separator1 = u' '
+ separator2 = u' -> '
+ content_html += format_html(update_sub_templ,
+ field=field_label,
+ separator1=mark_safe(separator1),
+ refer=subchange['refer'],
+ separator2=mark_safe(separator2),
+ current=subchange['current'])
+ content_html += u'
'
+ elif change.operation == EventChange.RAISE_FLAG:
+ icon = u'flag'
+ status = get_or_create_event_status(change.content)
+ content_html = format_html(raise_flag_templ,
+ bcontext=status.bootstrap_context,
+ label=status.label)
+ elif change.operation == EventChange.LOWER_FLAG:
+ icon = u'flag'
+ status = get_or_create_event_status(change.content)
+ content_html = format_html(lower_flag_templ,
+ bcontext=status.bootstrap_context,
+ label=status.label)
+ else:
+ icon = u'question-sign'
+ content_html = format_html(u'{content}', content=change.content)
+
html += format_html(change_templ,
+ icon=icon,
timestamp=timezone.localtime(change.timestamp).strftime('%Y-%m-%d %H:%M:%S %Z'),
user=username,
content=mark_safe(content_html))
+
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