From 46434977fb4b3f186f0044417f878cb59e890f26 Mon Sep 17 00:00:00 2001 From: David Taylor Date: Tue, 5 Apr 2016 04:18:19 +0100 Subject: [PATCH 1/9] Created merge admin action for Person, Venue and Organisation models. Added template. --- RIGS/admin.py | 46 +++++++++++++++++-- .../templates/RIGS/admin_associate_merge.html | 21 +++++++++ 2 files changed, 63 insertions(+), 4 deletions(-) create mode 100644 RIGS/templates/RIGS/admin_associate_merge.html diff --git a/RIGS/admin.py b/RIGS/admin.py index 18dc554e..a72c4705 100644 --- a/RIGS/admin.py +++ b/RIGS/admin.py @@ -4,16 +4,20 @@ from django.contrib.auth.admin import UserAdmin from django.utils.translation import ugettext_lazy as _ import reversion +from django.contrib.admin import helpers +from django.template.response import TemplateResponse +from django.contrib import messages +from django.db import transaction +from django.core.exceptions import ObjectDoesNotExist + # Register your models here. -admin.site.register(models.Person, reversion.VersionAdmin) -admin.site.register(models.Organisation, reversion.VersionAdmin) admin.site.register(models.VatRate, reversion.VersionAdmin) -admin.site.register(models.Venue, reversion.VersionAdmin) admin.site.register(models.Event, reversion.VersionAdmin) admin.site.register(models.EventItem, reversion.VersionAdmin) admin.site.register(models.Invoice) admin.site.register(models.Payment) +@admin.register(models.Profile) class ProfileAdmin(UserAdmin): fieldsets = ( (None, {'fields': ('username', 'password')}), @@ -33,4 +37,38 @@ class ProfileAdmin(UserAdmin): form = forms.ProfileChangeForm add_form = forms.ProfileCreationForm -admin.site.register(models.Profile, ProfileAdmin) +@admin.register(models.Person, models.Organisation, models.Venue) +class AssociateAdmin(reversion.VersionAdmin): + list_display = ('id', 'name','number_of_events') + search_fields = ['id','name'] + + actions = ['merge'] + + def number_of_events(self,obj): + return obj.latest_events.count() + + def merge(self, request, queryset): + if request.POST.get('post'): # Has the user confirmed which is the master record? + try: + masterObjectPk = request.POST.get('master') + masterObject = queryset.get(pk = masterObjectPk) + except ObjectDoesNotExist: + self.message_user(request, "An error occured. Did you select a 'master' record?",level=messages.ERROR) + return + + with transaction.atomic(), reversion.create_revision(): + for obj in queryset.exclude(pk = masterObjectPk): + events = obj.event_set.all() + for event in events: + masterObject.event_set.add(event) + obj.delete() + + self.message_user(request, "Objects successfully merged.") + return + else: # Present the confirmation screen + context = { + 'title': _("Are you sure?"), + 'queryset': queryset, + 'action_checkbox_name': helpers.ACTION_CHECKBOX_NAME, + } + return TemplateResponse(request, 'RIGS/admin_associate_merge.html', context, current_app=self.admin_site.name) \ No newline at end of file diff --git a/RIGS/templates/RIGS/admin_associate_merge.html b/RIGS/templates/RIGS/admin_associate_merge.html new file mode 100644 index 00000000..e30b2e55 --- /dev/null +++ b/RIGS/templates/RIGS/admin_associate_merge.html @@ -0,0 +1,21 @@ +{% extends "admin/base_site.html" %} +{% load i18n l10n %} + +{% block content %} +{% csrf_token %} + The following objects will be merged. Please select the 'master' record which you would like to keep. Other records will have associated events moved to the 'master' copy, and then will be deleted. + + {% for item in queryset %} + {{item.pk}} | {{item}} + {% endfor %} + + + {% for obj in queryset %} + + {% endfor %} + + + + + +{% endblock %} \ No newline at end of file From 33ce4b622d3a8e034178f0bee8a10d0f72caea3d Mon Sep 17 00:00:00 2001 From: David Taylor Date: Tue, 5 Apr 2016 04:18:53 +0100 Subject: [PATCH 2/9] Fixed bug with versioning interface when related objects are deleted --- RIGS/versioning.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/RIGS/versioning.py b/RIGS/versioning.py index 789fc5d7..c537de87 100644 --- a/RIGS/versioning.py +++ b/RIGS/versioning.py @@ -92,9 +92,16 @@ def model_compare(oldObj, newObj, excluded_keys=[]): if name in excluded_keys: continue # if we're excluding this field, skip over it - oldValue = getattr(oldObj, name, None) - newValue = getattr(newObj, name, None) + try: + oldValue = getattr(oldObj, name, None) + except ObjectDoesNotExist: + oldValue = None + try: + newValue = getattr(newObj, name, None) + except ObjectDoesNotExist: + newValue = None + try: bothBlank = (not oldValue) and (not newValue) if oldValue != newValue and not bothBlank: From ca6cddb3924bd185532a716ebb12aa9b79f951b7 Mon Sep 17 00:00:00 2001 From: David Taylor Date: Tue, 5 Apr 2016 11:50:34 +0100 Subject: [PATCH 3/9] Add comments display to versioning history (because why not). Maybe in future we could have a box people can type in before they save changes to an event... But that's a separate project --- RIGS/admin.py | 3 ++- RIGS/templates/RIGS/activity_feed_data.html | 3 +++ RIGS/templates/RIGS/activity_table.html | 2 ++ RIGS/templates/RIGS/version_history.html | 4 ++++ 4 files changed, 11 insertions(+), 1 deletion(-) diff --git a/RIGS/admin.py b/RIGS/admin.py index a72c4705..d8583e23 100644 --- a/RIGS/admin.py +++ b/RIGS/admin.py @@ -62,7 +62,8 @@ class AssociateAdmin(reversion.VersionAdmin): for event in events: masterObject.event_set.add(event) obj.delete() - + reversion.set_comment('Merging Objects') + self.message_user(request, "Objects successfully merged.") return else: # Present the confirmation screen diff --git a/RIGS/templates/RIGS/activity_feed_data.html b/RIGS/templates/RIGS/activity_feed_data.html index fc9af87e..e99baf8e 100644 --- a/RIGS/templates/RIGS/activity_feed_data.html +++ b/RIGS/templates/RIGS/activity_feed_data.html @@ -40,6 +40,9 @@ {% endif %} {% include 'RIGS/object_button.html' with object=version.new %} + {% if version.revision.comment %} + ({{ version.revision.comment }}) + {% endif %}
The following objects will be merged. Please select the 'master' record which you would like to keep. Other records will have associated events moved to the 'master' copy, and then will be deleted.