UPD: improved workflow code.

This commit is contained in:
2018-11-22 18:00:26 +01:00
parent 43af31232e
commit 6ecda70b54
5 changed files with 238 additions and 168 deletions

View File

@@ -19,6 +19,7 @@ from .. import choices
from .. import config
from .. import signals
from ..utils import get_ghost_user, get_system_user
from ..workflow import workflow
from .eventstatus import EventStatus, get_event_status
@@ -255,7 +256,7 @@ class Event(models.Model):
def get_absolute_url(self):
return reverse('dav_events:event_detail', kwargs={'pk': self.pk})
def save(self, **kwargs):
def save(self, implicit_update=False, **kwargs):
creating = False
original_text = ''
@@ -289,7 +290,7 @@ class Event(models.Model):
logger.warning('Event is not created by its owner (Current user: %s, Owner: %s)!', self.editor, owner)
self.owner = owner
creating = True
else:
elif not implicit_update:
original = Event.objects.get(id=self.id)
original_text = original.render_as_text(show_internal_fields=True)
@@ -300,98 +301,45 @@ class Event(models.Model):
if creating:
logger.info('Event created: %s', self)
signals.event_created.send(sender=self.__class__, event=self)
self.confirm_status('draft', self.editor)
else:
elif not implicit_update:
modified_text = self.render_as_text(show_internal_fields=True)
o_lines = original_text.split('\n')
m_lines = modified_text.split('\n')
diff_lines = list(difflib.unified_diff(o_lines, m_lines, n=len(m_lines), lineterm=''))
signals.event_updated.send(sender=self.__class__, event=self, diff=diff_lines, user=self.editor)
logger.info('Event updated: %s', self)
signals.event_updated.send(sender=self.__class__, event=self, diff=diff_lines, user=self.editor)
def _internal_update(self):
"""Safe changes on model instance without sending event_updated signal."""
if not self.id:
logger.critical('Event._internal_update() was called before Event was saved properly.')
raise Exception('Code is on fire!')
super(Event, self).save()
def update_flags(self, for_status=None):
if not self.id:
return
if isinstance(for_status, EventStatus):
code = for_status.code
else:
code = for_status
today = datetime.date.today()
midnight = datetime.time(00, 00, 00)
if code in (None, 'draft'):
if not self.flags.filter(status__code='draft').exists():
new_flag = EventFlag(event=self, status=get_event_status('draft'), timestamp=self.created_at)
new_flag.save()
logger.info('Detected draft state of Event %s', self)
if code in (None, 'published', 'publishing'):
if (self.flags.filter(status__code='publishing').exists() and
not self.flags.filter(status__code='published').exists()):
if not self.planned_publication_date:
flag = self.flags.filter(status__code='publishing').last()
new_status = get_event_status('published')
new_flag = EventFlag(event=self, status=new_status, timestamp=flag.timestamp)
new_flag.save()
logger.info('Detected published state of Event %s', self)
elif self.planned_publication_date <= today:
new_status = get_event_status('published')
new_timestamp = timezone.make_aware(datetime.datetime.combine(self.planned_publication_date,
midnight))
new_flag = EventFlag(event=self, status=new_status, timestamp=new_timestamp)
new_flag.save()
logger.info('Detected published state of Event %s', self)
if code in (None, 'expired'):
if not self.flags.filter(status__code='expired').exists():
expired_at = None
if self.alt_last_day:
if self.alt_last_day < today:
expired_at = self.alt_last_day
elif self.last_day:
if self.last_day < today:
expired_at = self.last_day
elif self.alt_first_day:
if self.alt_first_day < today:
expired_at = self.alt_first_day
elif self.first_day and self.first_day < today:
expired_at = self.first_day
if expired_at:
new_timestamp = timezone.make_aware(datetime.datetime.combine(expired_at, midnight))
new_flag = EventFlag(event=self, status=get_event_status('expired'), timestamp=new_timestamp)
new_flag.save()
logger.info('Detected expired state of Event %s', self)
def set_flag(self, status, **kwargs):
if not isinstance(status, EventStatus):
status = get_event_status(status)
kwargs['event'] = self
kwargs['status'] = status
flag = EventFlag(**kwargs)
flag.save()
logger.info('Flagging status \'%s\' for %s', status.code, self)
return flag
def is_flagged(self, status):
self.update_flags(status)
if isinstance(status, EventStatus):
code = status.code
else:
code = status
workflow.status_code_update(self, code)
if self.flags.filter(status__code=code).exists():
return True
return False
def get_status(self):
self.update_flags()
workflow.status_code_update(self)
last_flag = self.flags.last()
if last_flag:
return last_flag.status
return get_event_status('void')
def get_status_codes(self):
self.update_flags()
workflow.status_code_update(self)
return [flag.status.code for flag in self.flags.all()]
def confirm_status(self, status, user):
@@ -404,25 +352,25 @@ class Event(models.Model):
if flag:
return flag
if code == 'accepted':
if not self.is_flagged('submitted'):
logger.warning('Event.confirm_status(): yet not submitted event got accepted! (Event: %s)', self)
if not self.number:
self.number = self.get_next_number()
self._internal_update()
elif code == 'publishing' or code == 'published':
if not self.is_flagged('accepted'):
logger.warning('Event.confirm_status(): yet not accepted event got published! (Event: %s)', self)
valid, return_code, message = workflow.validate_status_code_update(code, self)
if not valid:
logger.warning(u'Invalid status update to \'%s\': %s Event: %s', code, message, self)
status_obj = get_event_status(code)
flag = EventFlag(event=self, status=status_obj, user=user)
flag.save()
logger.info('Flagging status \'%s\' for %s', code, self)
flag = self.set_flag(status=code, user=user)
workflow.status_code_update(self, code)
signals.event_status_updated.send(sender=self.__class__, event=self, flag=flag)
return flag
def get_next_number(self):
def get_number(self):
number = workflow.get_number(self)
if number:
return number
else:
return '%s**/%d' % (self.sport, self.first_day.year % 100)
def set_next_number(self):
counter = 0
year = self.first_day.year
@@ -431,8 +379,8 @@ class Event(models.Model):
qs = Event.objects.filter(number__isnull=False,
sport=self.sport,
first_day__gte=year_begin,
first_day__lte=year_end).order_by('-number')
last = qs.first()
first_day__lte=year_end).order_by('number')
last = qs.last()
if last:
match = re.match(r'^(?P<sport>[A-Z])(?P<count>[0-9][0-9]*)/(?P<year>[0-9][0-9]*)', last.number)
if match:
@@ -440,14 +388,9 @@ class Event(models.Model):
counter = int(gd['count'])
counter += 1
n = '%s%02d/%d' % (self.sport, counter, year % 100)
return n
def get_number(self):
if self.is_flagged('accepted') and self.number:
return self.number
else:
return '%s**/%d' % (self.sport, self.first_day.year % 100)
self.number = '%s%02d/%d' % (self.sport, counter, year % 100)
self.save(implicit_update=True)
return self.number
def get_formated_date(self, begin_date=None, end_date=None, format='normalized_long'):
if begin_date is None: