From 83b287a4185207c0debe63b56b13f2844b53dfb7 Mon Sep 17 00:00:00 2001 From: FreneticScribbler Date: Tue, 25 Jan 2022 10:29:46 +0000 Subject: [PATCH] Refactor merge logic to allow merging of users. Closes #473. --- RIGS/admin.py | 96 ++++++++++++++++++++++++++++++--------------------- 1 file changed, 56 insertions(+), 40 deletions(-) diff --git a/RIGS/admin.py b/RIGS/admin.py index 62c840f5..e7521936 100644 --- a/RIGS/admin.py +++ b/RIGS/admin.py @@ -8,6 +8,7 @@ from django.db.models import Count from django.forms import ModelForm from django.template.response import TemplateResponse from django.utils.translation import gettext_lazy as _ +from django.db import IntegrityError from reversion import revisions as reversion from reversion.admin import VersionAdmin @@ -21,45 +22,11 @@ admin.site.register(models.EventItem, VersionAdmin) admin.site.register(models.Invoice, VersionAdmin) -def approve_user(modeladmin, request, queryset): - queryset.update(is_approved=True) - - -approve_user.short_description = "Approve selected users" - - -@admin.register(models.Profile) -class ProfileAdmin(UserAdmin): - # Don't know how to add 'is_approved' whilst preserving the default list... - list_filter = ('is_approved', 'is_active', 'is_staff', 'is_superuser', 'groups') - fieldsets = ( - (None, {'fields': ('username', 'password')}), - (_('Personal info'), { - 'fields': ('first_name', 'last_name', 'email', 'initials', 'phone')}), - (_('Permissions'), {'fields': ('is_approved', 'is_active', 'is_staff', 'is_superuser', - 'groups', 'user_permissions')}), - (_('Important dates'), { - 'fields': ('last_login', 'date_joined')}), - ) - add_fieldsets = ( - (None, { - 'classes': ('wide',), - 'fields': ('username', 'password1', 'password2'), - }), - ) - form = user_forms.ProfileChangeForm - add_form = user_forms.ProfileCreationForm - actions = [approve_user] - - class AssociateAdmin(VersionAdmin): - list_display = ('id', 'name', 'number_of_events') search_fields = ['id', 'name'] list_display_links = ['id', 'name'] actions = ['merge'] - merge_fields = ['name'] - def get_queryset(self, request): return super(AssociateAdmin, self).get_queryset(request).annotate(event_count=Count('event')) @@ -71,17 +38,37 @@ class AssociateAdmin(VersionAdmin): 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) + master_object_pk = request.POST.get('master') + master_object = queryset.get(pk=master_object_pk) 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) + for obj in queryset.exclude(pk=master_object_pk): + # If we're merging profiles, merge their training information + if hasattr(obj, 'event_mic'): + events = obj.event_mic.all() + for event in events: + master_object.event_mic.add(event) + for qual in obj.qualifications_obtained.all(): + try: + with transaction.atomic(): + master_object.qualifications_obtained.add(qual) + except IntegrityError: + existing_qual = master_object.qualifications_obtained.get(item=qual.item, depth=qual.depth) + existing_qual.notes += qual.notes + existing_qual.save() + for level in obj.level_qualifications.all(): + try: + with transaction.atomic(): + master_object.level_qualifications.add(level) + except IntegrityError: + continue # Exists, oh well + else: + events = obj.event_set.all() + for event in events: + master_object.event_set.add(event) obj.delete() reversion.set_comment('Merging Objects') @@ -107,6 +94,35 @@ class AssociateAdmin(VersionAdmin): return TemplateResponse(request, 'admin_associate_merge.html', context) +@admin.register(models.Profile) +class ProfileAdmin(UserAdmin, AssociateAdmin): + list_display = ('username', 'name', 'is_approved', 'is_staff', 'is_superuser', 'is_supervisor', 'number_of_events') + list_display_links = ['username'] + fieldsets = ( + (None, {'fields': ('username', 'password')}), + (_('Personal info'), { + 'fields': ('first_name', 'last_name', 'email', 'initials', 'phone')}), + (_('Permissions'), {'fields': ('is_approved', 'is_active', 'is_staff', 'is_superuser', + 'groups', 'user_permissions')}), + (_('Important dates'), { + 'fields': ('last_login', 'date_joined')}), + ) + add_fieldsets = ( + (None, { + 'classes': ('wide',), + 'fields': ('username', 'password1', 'password2'), + }), + ) + form = user_forms.ProfileChangeForm + add_form = user_forms.ProfileCreationForm + actions = ['approve_user', 'merge'] + + merge_fields = ['username', 'first_name', 'last_name', 'initials', 'email', 'phone', 'is_supervisor'] + + def approve_user(modeladmin, request, queryset): + queryset.update(is_approved=True) + + @admin.register(models.Person) class PersonAdmin(AssociateAdmin): list_display = ('id', 'name', 'phone', 'email', 'number_of_events')